Im trying to animate a figure created in Scene Builder, using the Transition class.
Controller:
public class Controller{
#FXML
private Line line1;
#FXML
private Line line2;
#FXML
private Line line3;
#FXML
private Rectangle rectangle1;
private double mult_factor;
private double rectangle_height;
public Controller(){
final Animation anim = new Transition() {
{
setCycleDuration(Duration.millis(3000));
}
#Override
protected void interpolate(double frac) {
rectangle_height = rectangle1.getHeight();
mult_factor = frac * 5.8;
rectangle1.setHeight(rectangle_height * mult_factor);
}
};
}}
Main Class:
public class FormTest extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("The container test");
primaryStage.setHeight(600);
primaryStage.setWidth(600);
Pane pane = (Pane) FXMLLoader.load(FormTest.class.getResource("conf.fxml"));
Controller ctr = new Controller();
primaryStage.setScene(new Scene(pane));
primaryStage.show();
}}
FXML File:
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="Controller">
<children>
<Line fx:id="line1" endX="100.0" endY="300.0" layoutX="106.0" layoutY="70.0" startX="100.0" />
<Line fx:id="line2" endX="100.0" endY="300.0" layoutX="300.0" layoutY="70.0" startX="100.0" />
<Line fx:id="line3" endX="193.0" layoutX="207.0" layoutY="370.0" />
<Rectangle fx:id="rectangle1" arcHeight="5.0" arcWidth="5.0" fill="DODGERBLUE" height="42.0" layoutX="207.0" layoutY="327.0" stroke="BLACK" strokeType="INSIDE" width="192.0" />
</children>
</Pane>
The Scene just appears but nothing happens, the animation does not occur. What am I doing wrong there?
This should do the trick!
public Controller(){
> final Animation anim = new Transition() {
> {
> setCycleDuration(Duration.millis(3000));
> }
> #Override
> protected void interpolate(double frac) {
> rectangle_height = rectangle1.getHeight();
> mult_factor = frac * 5.8;
> rectangle1.setHeight(rectangle_height * mult_factor);
> }
> };
> anim.play(); // <- start the actual animation
}
}
You never start the animation, which you can do in the Controller's initialize() method:
public class Controller{
#FXML
private Line line1;
#FXML
private Line line2;
#FXML
private Line line3;
#FXML
private Rectangle rectangle1;
private double mult_factor;
private double rectangle_height;
public void initialize() {
final Animation anim = new Transition() {
{
setCycleDuration(Duration.millis(3000));
}
#Override
protected void interpolate(double frac) {
rectangle_height = rectangle1.getHeight();
mult_factor = frac * 5.8;
rectangle1.setHeight(rectangle_height * mult_factor);
}
};
anim.play();
}
}
The animation probably isn't doing what you want it to do, but that will at least make it run.
Related
I have two controllers:
Main which contains TableView Tab which displays SQLITE database tables (which contain different number of columns) in tabular format, and
Rem which contains a button which dictates which database to display (there are many such controllers).
Now if I create a method in Main which is responsible for updating and displaying TableView contents, how do I use that method in other controller?
I created two static ObservableList variables columns and rows and bind them to Tab in Main's initialize.
APP.java
public class App extends Application {
private static Scene scene;
public static Connection conn;
#Override
public void start(Stage stage) throws IOException {
try{
conn=java.sql.DriverManager.getConnection("jdbc:sqlite:sample.db");
if(conn!=null){
conn.createStatement().execute("CREATE TABLE IF NOT EXISTS tab1(Field0 TEXT, Field1 TEXT, Field2 TEXT);");
conn.createStatement().execute("CREATE TABLE IF NOT EXISTS tab2(Field3 TEXT, Field4 TEXT);");
}
}catch(Exception ex){
System.out.println(ex);
}
scene = new Scene(loadFXML("main"), 640, 480);
stage.setScene(scene);
stage.show();
}
private static Parent loadFXML(String fxml) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
return fxmlLoader.load();
}
public static void main(String[] args) {
launch();
}
public static ResultSet getRS(String table){
String sql="SELECT * FROM "+table;
ResultSet rs=null;
try{
rs=conn.createStatement().executeQuery(sql);
}catch(Exception ex){
System.out.println(ex);
}
return rs;
}
}
MAIN.FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nic.testfx.Main">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" onAction="#loadRem" text="Load Remaining" />
</items>
</Menu>
</menus>
</MenuBar>
<TableView fx:id="Tab" prefHeight="200.0" prefWidth="200.0" />
<VBox fx:id="remPane" prefHeight="200.0" prefWidth="100.0" />
</children>
</VBox>
MAIN.JAVA
public class Main implements Initializable {
#FXML
public TableView<ObservableList<String>> Tab;
#FXML
private VBox remPane;
#Override
public void initialize(URL url, ResourceBundle rb) {
Tab.itemsProperty().bind(getTabRow());
}
public void makeTable(ResultSet rs){
try{
var rsm=rs.getMetaData();
ObservableList<TableColumn<ObservableList<String>,String>>cols=FXCollections.observableArrayList();
for(int i=0;i<rsm.getColumnCount();i++){
final int j=i;
TableColumn<ObservableList<String>,String> col=new TableColumn(rsm.getColumnName(i+1));
col.setCellValueFactory(param->new SimpleStringProperty(param.getValue().get(j)));
cols.add(col);
}
ObservableList<ObservableList<String>> arows=FXCollections.observableArrayList();
while(rs.next()){
ObservableList<String> row=FXCollections.observableArrayList();
for(int i=1;i<=rsm.getColumnCount();i++){
row.add(rs.getString(i));
}
arows.add(row);
}
setTable(cols,arows);
}catch(Exception ex){
System.out.println(ex);
}
}
private static final ObservableList<TableColumn<ObservableList<String>,String>> columns=FXCollections.observableArrayList();
private static final javafx.beans.property.ListProperty<ObservableList<String>> rows=new javafx.beans.property.SimpleListProperty();
private javafx.beans.property.ListProperty getTabRow(){
Tab.getColumns().clear();
Tab.getColumns().addAll(columns);
return rows;
}
private static void setTable(ObservableList<TableColumn<ObservableList<String>,String>>c,ObservableList<ObservableList<String>> r){
columns.setAll(c);
rows.set(r);
}
#FXML
private void loadRem(ActionEvent event) {
try{
for(int i=remPane.getChildren().size()-1;i>=0;i--){
remPane.getChildren().remove(i);
}
javafx.fxml.FXMLLoader fxmlLoader=new javafx.fxml.FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("rem.fxml"));
javafx.scene.layout.Pane panel=fxmlLoader.load();
remPane.getChildren().add(panel);
makeTable(App.getRS("tab1"));
}catch(Exception ex){
System.out.println(ex);
}
}
}
REM.FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.VBox?>
<VBox alignment="CENTER" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nic.testfx.Rem">
<children>
<Button fx:id="btn" mnemonicParsing="false" onAction="#loadTab" text="Button" />
</children>
</VBox>
REM.JAVA
public class Rem implements Initializable {
#FXML
private Button btn;
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
#FXML
private void loadTab(ActionEvent event) {
try{
var fxml=new javafx.fxml.FXMLLoader(App.class.getResource("main.fxml"));
fxml.load();
Main controller=fxml.getController();
var rs=App.getRS("tab2");
controller.makeTable(rs);
}catch(Exception ex){
System.out.println(ex);
}
}
}
OK I got it.
Created a java class which encapsulate method makeTable:
MODEL.JAVA
public class Model{
private final TableView table;
public Model(TableView t){
this.table=t;
}
public void makeTable(ResultSet rs){
ObservableList<TableColumn<ObservableList<String>,String>>tabcols=FXCollections.observableArrayList();
ObservableList<ObservableList<String>>tabrows=FXCollections.observableArrayList();
//Create TableColumns and add to tabcols;
while(rs.next()){
//Create ObservableList<String>, get data from rs, and add to tabrows
}
this.table.getColumns().setAll(tabcols);
this.table.getItems().setAll(tabrows);
}
}
Next, in Controller file Main.java created a static instance of Model:
MAIN.JAVA
public class Main implements Initializable{
#FXML
private TableView<ObservableList<String>> Tab;
static Model model;
#Override
public void initialize (URL url, ResourceBundle rb){
model=new Model(Tab);
}
}
Now I can use model from Rem controller:
REM.JAVA
public class Rem implements Initializable{
#FXML
private Button btn;
#Override
public void initialize (URL url, ResourceBundle rb){
//TODO
}
#FXML
private void loadTab(ActionEvent event){
var rs=App.getRS("tab2");
Main.model.makeTable(rs);
}
i have small application to manage my tasks. I created DB(sqlite), and i store there a data.
After i log in i got dashboard scene. On dashboard scene i have implemented ObservableList which store taskList and their details. This list is updated always when i add/modify/delete tasks.
I have problem when i add/modify/delete task, when i do it the list is correctly updated but the item witch i add/modify is not selected after operation although i have that implemented.
The Main code:
public class Main extends Application {
private static Main instance;
public BorderPane mainBorderPane;
private Stage primaryStage;
public static Main getInstance() {
return instance;
}
#Override
public void start(Stage primaryStage) throws Exception{
instance = this;
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Hello World");
showDashboardScene();
}
private void showDashboardScene() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/sample/dashboard.fxml"));
mainBorderPane = loader.load();
Scene scene = new Scene(mainBorderPane);
primaryStage.setScene(scene);
primaryStage.initStyle(StageStyle.UTILITY);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
DashboardController:
public class DashboardController {
private ObservableList<Task> tasks = FXCollections.observableArrayList();
#FXML
private ListView<Task> taskListView;
public void initialize() throws SQLException {
tasks = TaskData.getInstance().getTaskList();
findListChange();
taskListView.setItems(tasks);
taskListView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
taskListView.getSelectionModel().selectFirst();
}
public void refreshView() {
tasks = TaskData.getInstance().getTaskList();
findListChange();
taskListView.setItems(tasks);
taskListView.getSelectionModel().selectedItemProperty();
taskListView.getSelectionModel().selectLast();
}
private void findListChange() {
this.taskListView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Task>() {
#Override
public void changed(ObservableValue<? extends Task> observable, Task oldValue, Task newValue) {
if (newValue != null) {
Task item = taskListView.getSelectionModel().getSelectedItem();
}
}
});
}
}
dashboard.fxml
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.ListView?>
<BorderPane fx:controller="sample.DashboardController" xmlns:fx="http://javafx.com/fxml" >
<top>
<fx:include fx:id="mainMenu" source="/sample/menu.fxml"/>
</top>
<left>
<ListView fx:id="taskListView"/>
</left>
</BorderPane>
MenuController
public class MenuController {
public void showDialog() throws SQLException, IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/sample/addTask.fxml"));
loader.load();
AddTaskController controller = loader.getController();
controller.showAddTaskDialog();
}
}
menu.fxml
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuItem?>
<MenuBar fx:controller="sample.MenuController" xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml ">
<Menu text="Tasks">
<MenuItem text="Add" onAction="#showDialog"/>
</Menu>
</MenuBar>
addTask.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.GridPane?>
<DialogPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="sample.AddTaskController">
<content>
<GridPane vgap="10" hgap="10" >
<Label text="Name" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
<TextField fx:id="taskNameTF" GridPane.rowIndex="0" GridPane.columnIndex="1"/>
</GridPane>
</content>
</DialogPane>
AddTaskController:
public class AddTaskController {
#FXML
private TextField taskNameTF;
#FXML
public void showAddTaskDialog()throws IOException, SQLException {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.initOwner(Main.getInstance().mainBorderPane.getScene().getWindow());
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/sample/addTask.fxml"));
try {
dialog.getDialogPane().setContent(loader.load());
} catch (IOException e) {e.printStackTrace();
System.out.println("Nie udało sie wyświetlić panelu, prosimy spróbować później");
e.printStackTrace();
return;
}
dialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
dialog.getDialogPane().getButtonTypes().add(ButtonType.CANCEL);
Optional<ButtonType> result = dialog.showAndWait();
if(result.isPresent() && result.get().equals(ButtonType.OK)) {
AddTaskController controller = loader.getController();
controller.addTaskToList();
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/sample/dashboard.fxml"));
fxmlLoader.load();
DashboardController dashboardController = fxmlLoader.getController();
dashboardController.refreshView();
System.out.println("OK, pressed");
} else {
System.out.println("CANCEL, pressed");
}
}
private void addTaskToList() {
String taskName = taskNameTF.getText().trim();
TaskData.getInstance().addTaskToList(new Task(taskName));
}
}
Task
public class Task {
private String taskName;
public Task(String taskName) {
this.taskName = taskName;
}
#Override
public String toString() {
return taskName.toString();
}
}
TaskData
public class TaskData {
private ObservableList<Task> tasks = FXCollections.observableArrayList();
private static TaskData instance = new TaskData();
public static TaskData getInstance() {
return instance;
}
public ObservableList<Task> getTaskList() {
return tasks;
}
public void addTaskToList(Task task) {
instance.tasks.add(task);
}
}
i'm not sure but when i initialize a application, reference to ListView is different than reference of list when i add/modify item. I think this is the problem but i dont know how to fix it ;/
I've found such a problem:
Having a MainWindow and 2 SubWindows, but I've got exceptions like:
-Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
-Caused by: java.lang.NullPointerException: Location is required.
-[...]
-at ApplicationForTests.SubWin1.SubWin1.display(SubWin1.java:14)
> Parent root = FXMLLoader.load(getClass().getResource("ApplicationForTests/SubWin1UI.fxml"));
-[...]
-at ApplicationForTests.MainController.openSub1(MainController.java:22)
> subWin1.display();
-[...]
-Exception in thread "Thread-3" java.lang.IncompatibleClassChangeError
Main:
public class Main extends Application {
public static BdcsDAO db = new BdcsDAO();
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("MainUI.fxml"));
primaryStage.setTitle("Main window");
primaryStage.setScene(new Scene(root, 500, 400));
primaryStage.show();
db.connect();
}
public static void main(String[] args) {launch(args);}
MainController:
public class MainController {
#FXML
Button button1;
#FXML
Button button2;
#FXML
public void openSub1() {
SubWin1 subWin1 = new SubWin1();
try {
subWin1.display();
} catch (IOException e) {
e.printStackTrace();
}
}
#FXML
public void openSub2() {
SubWin2 subWin2 = new SubWin2();
try {
subWin2.display();
} catch (IOException e) {
e.printStackTrace();
}
}
}
MainUI:
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ApplicationForTests.MainController">
<children>
<Button fx:id="button1" onAction="#openSub1" layoutX="268.0" layoutY="185.0" mnemonicParsing="false" text="SubWin1" />
<Button fx:id="button2" onAction="#openSub2" layoutX="268.0" layoutY="285.0" mnemonicParsing="false" text="SubWin2" />
</children>
</AnchorPane>
SubWin1:
public class SubWin1 {
public void display() throws IOException {
Stage window = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("ApplicationForTests/SubWin1UI.fxml"));
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle("Sub window no. 1");
window.setScene(new Scene(root, 800, 500));
window.show();
}
}
SubWin1Controller:
public class SubWin1Controller {
#FXML
Button button;
#FXML
public void loadTableView() throws SQLException {
setAlarmsTableView(Main.db.getSampleResultSet());
}
#FXML
private TableView<AlarmType> alarmsTableView;
#FXML
private TableColumn<?, ?> columnDeviceIndex;
#FXML
private TableColumn<?, ?> columnAlgorithmType;
private ObservableList<AlarmType> dataAlarms = FXCollections.observableArrayList();
public void setAlarmsTableView(ResultSet rs) throws SQLException {
columnDeviceIndex.setCellValueFactory(new PropertyValueFactory<>("deviceIndex"));
columnAlgorithmType.setCellValueFactory(new PropertyValueFactory<>("algorithmType"));
while (rs.next()) {
dataAlarms.add(new AlarmType(rs.getInt(1), rs.getInt(2));
}
alarmsTableView.setItems(dataAlarms);
}
}
I have seen a lot of question similar to mine, but I didn't figure it out how to solve my problem, so there is my code:
I have a simple main:
MainClassFXGui.java
public class MainClassFXGui extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Assicurazione");
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
and three fxml files, one of them that contains the other two, by the tag
<fx:include source="MyTab1.fxml" />
MyProgramMainGuiTab.fxml
...
<TabPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="5000.0" prefWidth="5000.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab closable="false" text="MyTab1">
<content>
<fx:include source="MyTab1.fxml" />
</content>
</Tab>
<Tab closable="false" text="MyTab2">
<content>
<fx:include source="MyTab2.fxml" />
</content>
</Tab>
</tabs>
</TabPane>
...
and three controller:
MyProgramMainGuiTabController.java
....
#FXML
private Label LeftSt;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
LeftSt.setText("");
}
public void setLeftSt(String st){
LeftSt.setText(st);
}
...
MyTab1Controller.java
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}
I tried in this way:
MyTab1Controller.java
private MyProgramMainGuiTabController controller;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
controller.setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
FXMLLoader fxmlLoader = new
FXMLLoader(getClass().getResource("MyProgramMainGuiTab.fxml"));
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
controller = (MyProgramMainGuiTabController)fxmlLoader.getController();
}
But I have a null pointer exception or if I move the code for the instanzialization of the object 'controller' in the handleButtonAction function, I don't have any error, but the label does not change.
Maybe I can create a static Scene and a static Stage in the MainClassFXGui.java?
but then I don't know how I could use them...
MainClassFXGui.java
public class MainClassFXGui extends Application {
static private Scene scene;
static private Stage stage;
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));
this.scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Assicurazione");
stage.show();
this.stage = stage;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public static Scene getScene(){
return AssicurazioneFXGui.scene;
}
public static Stage getStage(){
return AssicurazioneFXGui.stage;
}
}
can I do something with getScene() or getStage()? any idea or suggest?
thanks to everyone
Define a StringProperty in MyTab1Controller, with the usual methods:
public class MyTab1Controller {
private final StringProperty leftSt = new SimpleStringProperty();
public StringProperty leftStProperty() {
return leftSt ;
}
public final String getLeftSt() {
return leftStProperty().get();
}
public final void setLeftSt(String leftSt) {
leftStProperty().set(leftSt);
}
// ...
#FXML
public void handleButtonAction() {
setLeftSt(...);
}
// ...
}
Now assign an fx:id attribute to the fx:include tag:
<Tab closable="false" text="MyTab1">
<content>
<fx:include fx:id="myTab1" source="MyTab1.fxml" />
</content>
</Tab>
This means you can inject the controller for MyTab1.fxml into the controller for the FXML where it is included (MyProgramMainGuiTabController):
public class MyProgramMainGuiTabController {
#FXML
private MyTab1Controller myTab1Controller ;
}
and then you can just observe the property and update the label when it changes:
public class MyProgramMainGuiTabController {
#FXML
private MyTab1Controller myTab1Controller ;
#FXML
private Label leftSt;
public void initialize() {
leftSt.setText("");
myTab1Controller.leftStProperty().addListener((obs, oldValue, newValue) ->
leftSt.setText(newValue));
}
}
Note the rule here is that the field name for the controller is the value of the fx:id attribute with the word "Controller" appended: myTab1 in the fx:id resolves to myTab1Controller for the field where the controller is injected. See NestedControllers for more information.
At the moment I have solved in this way. If anyway someone has a better solution, please write. Also because this does not solve the problem if I need to execute a function.. thanks
MyProgramMainGuiTabController.fxml
...
#FXML
private Label LeftSt;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
LeftSt.setText("");
}
...
MyTab1Controller.fxml
#FXML
private Button myObject;
private Scene scene;
private Label lblDataLeft;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
setLeftSt("this works!");
}
public void setLeftSt(String st){
if(this.scene == null)
this.scene = myObject.getScene();
if(this.lblDataLeft==null)
this.lblDataLeft = (Label) scene.lookup("#LeftSt");
if (this.lblDataLeft!=null)
this.lblDataLeft.setText(st);
}
I would like to develop a mouse entered method that swaps the locations of two buttons in real time using FXML and JavaFX which I am unfortunately very new to. Relocate(x,y), get/setLayoutX/Y and below get/setTranslateX/Y all throw IllegalArgumentEceptions with not much more understandable information in the stack trace. What is the preferred Button Property to use in order to get and then set a real-time location swap?
#FXML protected void neinHover (ActionEvent evt){
double jTmpX, jTmpY, nTmpX, nTmpY;
nTmpX = neinButton.getTranslateX();
nTmpY = neinButton.getTranslateY();
jTmpX = jaButton.getTranslateX();
jTmpY = jaButton.getTranslateY();
jaButton.setTranslateX(nTmpX);
jaButton.setTranslateY(nTmpY);
neinButton.setTranslateX(jTmpX);
neinButton.setTranslateY(jTmpY);
}
I supose you want something like this:
FXML:
<fx:root onMouseClicked="#swap" type="Pane" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
<children>
<Button fx:id="b1" mnemonicParsing="false" text="1" />
<Button fx:id="b2" layoutX="90.0" mnemonicParsing="false" text="2" />
</children>
</fx:root>
Controller:
public class MockPane extends Pane {
#FXML
private Button b1;
#FXML
private Button b2;
public MockPane() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(
"MockPane.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
#FXML
private void swap() {
double b1x = b1.getLayoutX();
double b1y = b1.getLayoutY();
double b2x = b2.getLayoutX();
double b2y = b2.getLayoutY();
b1.setLayoutX(b2x);
b1.setLayoutY(b2y);
b2.setLayoutX(b1x);
b2.setLayoutY(b1y);
}
}
App:
public class MockApp extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage stage) throws Exception {
MockPane root = new MockPane();
Scene scene = new Scene(root, 200, 100);
stage.setScene(scene);
stage.show();
}
}