Reputation: 397
I just started using JavaFX Scene Builder to build a small application.
It is made up of a controller class 'Login.java' which belongs to 'login.fxml', in which the FXML file 'registrierung.fxml' is loaded via a method called 'registrationClicked(ActionEvent event)':
public class Login {
@FXML
private void registrationClicked(ActionEvent event){
try{
((Node) (event.getSource())).getScene().getWindow().hide();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/fxml/registrierung.fxml"));
Parent root = (Parent) loader.load();
Stage stage = new Stage();
Scene scene = new Scene(root);
stage.setTitle("Registration");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
} catch(IOException e){
e.printStackTrace();
}
}
Now I want to get a reference to the stage of 'registrierung.fxml' in the controller class 'Registrierung.java' via the root node vboxRoot:
@FXML
private VBox vboxRoot;
Stage stage = (Stage) vboxRoot.getScene().getWindow();
However 'getScene()' always leads to a NullPointerException. The controller classes for both FXML files are adjusted in Scene Builder.
This is how I set up the rood node in 'registrierung.fxml':
<VBox fx:id="vboxRoot" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="267.0" prefWidth="355.0" stylesheets="@../css/styles.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="businesslogik.Registrierung">
What am I doing wrong?
Upvotes: 19
Views: 23360
Reputation: 181
Implementing the Initializable interface did not work for me(Java 8). The method getScene() always returned null for me. So i had to do the following:
FXMLLoader loader = new FXMLLoader(getClass().getResource("MyGui.fxml"));
Parent root = (Parent)loader.load();
//do stage and scene stuff - i skip it here
MyController controller = (MyController)loader.getController();
stage.setOnShown(controller::adjustUI);
And in the controller i have:
public void adjustUI(WindowEvent event) {
Scene scene = myComponent.getScene();
//do stuff and do ui adjustments here
}
Upvotes: 2
Reputation: 4209
I have run into this issue and have found by placing a call to a method like this (When the scene becomes visible and is attached to the node, this will fire):
private void determinePrimaryStage() {
rootPane.sceneProperty().addListener((observableScene, oldScene, newScene) -> {
if (oldScene == null && newScene != null) {
// scene is set for the first time. Now its the time to listen stage changes.
newScene.windowProperty().addListener((observableWindow, oldWindow, newWindow) -> {
if (oldWindow == null && newWindow != null) {
primaryStage = (Stage)newWindow;
}
});
}
});
}`
Then I can do something like this later:
if(primaryStage == null) {
Platform.runLater(()-.{......
}else {
//do whatever
}
Hope this helps.
Upvotes: 9
Reputation:
you are trying to get the scene for an object that has not been initialized yet. if you were doing the same operation in
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
Stage stage = (Stage) vboxRoot.getScene().getWindow();
}
or if you have an event that triggers once you click something (which executes after the scene has loaded)
@FXML
private void action(ActionEvent event) throws IOException {
Stage stage = (Stage) vboxRoot.getScene().getWindow();
}
This would work!
Upvotes: 12