JavaFX - getScene() 返回 null

2022-09-02 13:19:34

我刚刚开始使用JavaFX Scene Builder来构建一个小型应用程序。

它由一个控制器类“Login.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();
    }
}

现在我想通过根节点 vboxRoot 获取控制器类 'Registrierung.java' 中 'registrierung.fxml' 阶段的引用:

@FXML
private VBox vboxRoot;

Stage stage = (Stage) vboxRoot.getScene().getWindow();

然而,'getScene()'总是导致NullPointerException。两个 FXML 文件的控制器类都在场景生成器中进行调整。

这就是我在'registrierung.fxml'中设置rood节点的方式:

<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">

我做错了什么?


答案 1

您正在尝试获取尚未初始化的对象的场景。如果您在 中执行相同的操作

@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();
}

这将起作用!


答案 2

我遇到了这个问题,并通过调用这样的方法找到了(当场景变得可见并附加到节点时,这将触发):

 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
}

希望这有帮助。


推荐