I have a very simple fxml file, with a checkbox:
...
<AnchorPane id="AnchorPane" xmlns:fx="http://javafx.com/fxml" fx:controller="jfx01.T01">
...
<CheckBox fx:id="checkBox1" text="CheckBox" />
...
the very simple controller class is the following:
public class T01 extends Application {
@FXML protected CheckBox checkBox1;
@Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("t01.fxml"));
primaryStage.setScene(new Scene(root));
primaryStage.show();
//here, here is the problem!
System.out.println("checkBox1==null? "+ (checkBox1==null?"yes":"no"));
}
}
checkBox1==null? yes
Inside the "start" method the components are obviously created, but not yet assigned to @FXML fields of the controller class. As a test that there aren't other errors, i've added a button and an event. There the checkBox1 IS assigned!
@FXML protected void handleButton1Action(ActionEvent event) {
System.out.println("button pressed");
checkBox1.setSelected(!checkBox1.isSelected());
}
If I can't use start method because init is not yet complete, what is the first method available where the init is complete and so the components are available?
The Controller should implement javafx.fxml.Initializable
and override initialize(URL arg0, ResourceBundle res)
method. The CheckBox checkBox1
will be initialized and be avaliable in that initialize
method for you by the FXMLLoader. The convenience way is to separate the Controller and Main (that extends Application) classes, so app starting/entry point and the FXML file controller should be 2 different classes.
You can access the main Stage with in the Controller with this:
Node source = (Node) event.getSource();
Stage stage = (Stage) source.getScene().getWindow();