Issue
I'm worked with java for a year and am pretty new to javaFX and have been have been following a basic tutorial so far using scenebuilder. I've tried to apply a translatetransition to my button so far but it doesn't seem to move at all. When I run the program the scene with its background is displayed, but the button just stays in its defined start position in scenebuilder and won't move. After checking other similar questions on this site I've made sure that I implemented Initializable and adding @Override before my initialize function, and I've made sure my transition is played. I've tried the translatetransition on a rectangle too and it won't move. Might just be that I'm using eclipse and not netbeans
Driver Class:
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
//import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
Parent myroot = FXMLLoader.load(getClass().getClassLoader().getResource("MyFxml.fxml"));
//BorderPane root = new BorderPane();
Scene scene = new Scene(myroot);
//scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
FXML
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ImageView fitHeight="413.0" fitWidth="638.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../../Downloads/campusmap.png" />
</image>
</ImageView>
<AnchorPane prefHeight="200.0" prefWidth="200.0">
<children>
<Rectangle fx:id="myrectangle" arcHeight="5.0" arcWidth="5.0" fill="#128cff" height="200.0" layoutX="14.0" layoutY="64.0" stroke="BLACK" strokeType="INSIDE" width="200.0" />
<Button fx:id="startbutton" layoutX="202.0" layoutY="232.0" mnemonicParsing="false" prefHeight="64.0" prefWidth="197.0" style="-fx-background-color: #FFC0CB; -fx-background-radius: 100;" text="Start Program">
<font>
<Font name="Comic Sans MS" size="12.0" />
</font></Button>
</children>
</AnchorPane>
</children>
</StackPane>
FXML Controller
package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;
import javafx.animation.TranslateTransition;
public class MyFxmlController implements Initializable{
@FXML
private Button startbutton;
@FXML
private Rectangle myrectangle;
@Override
public void initialize(URL url, ResourceBundle rb) {
TranslateTransition transition = new TranslateTransition();
transition.setDuration(Duration.seconds(4));
transition.setNode(startbutton);
transition.setToX(-200);
transition.setToY(-200);
transition.play();
}
}
Solution
You are not "linking" your controller to the FXML document. So when you display the FXML layout, the Transition
code is never executed.
You have a couple of options to do this. In SceneBuilder, you can specify the controller class here:
This will add the fx:controller
attribute to your FXML file:
fx:controller="temp.translate.MyFxmlController"
Obviously, you'll need to use your own package paths here.
The other option is to specify the controller in your Java code by updating your loading of the FXML document.
In order to do so, you'll need to get a reference to the FXMLLoader
and set the controller there. You can change your start()
method like this:
@Override
public void start(Stage primaryStage) {
try {
// Create a new FXMLLoader and set the FXML path
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyFxml.fxml"));
// Set the controller for this FXML document
loader.setController(new MyFxmlController());
// Load the FXML into your Parent node
Parent myRoot = loader.load();
//BorderPane root = new BorderPane();
Scene scene = new Scene(myRoot);
//scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
Note: If you've specified the controller in your FXML via fx:controller
, you cannot also specify it in your Java code, and vice versa. You may only define the controller in one place or the other, so it's really personal preference and depends on your needs.
Answered By - Zephyr