JavaFX-getScene () возвращает null

Я только начал использовать JavaFX Scene Builder для создания небольшого приложения.

Он состоит из логина класса контроллера.java", который принадлежит " login.fxml", в котором файл FXML " registrierung.fxml "загружается с помощью метода под названием" 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();
    }
}

Теперь я хочу получить ссылку на этап " registrierung.fxml "в классе контроллера" Registrierung.java ' через корневой узел vboxRoot:

@FXML
private VBox vboxRoot;

Stage stage = (Stage) vboxRoot.getScene().getWindow();
'getScene ()' всегда приводит к NullPointerException. Классы контроллеров для обоих файлов FXML настраиваются в Scene Builder.

вот как я настроил узел rood в ' 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">

что я делаю не так?

2 ответов


вы пытаетесь получить сцену для объекта, который еще не был инициализирован. если бы вы делали ту же операцию в

@Override 
    public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
    Stage stage = (Stage) vboxRoot.getScene().getWindow();
}

или если у вас есть событие, которое запускается после нажатия на что-то (которое выполняется после загрузки сцены)

@FXML
private void action(ActionEvent event) throws IOException {
    Stage stage = (Stage) vboxRoot.getScene().getWindow();
}

это будет работать!


я столкнулся с этой проблемой и нашел, разместив вызов такого метода (когда сцена становится видимой и прикреплена к узлу, это сработает):

 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;
                    }
                });
            }
        });
    }`

тогда я могу сделать что-то подобное позже:

if(primaryStage == null) {
    Platform.runLater(()-.{......
}else {
   //do whatever
}

надеюсь, что это помогает.