java JavaFX - getScene() 返回 null

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30464238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:10:32  来源:igfitidea点击:

JavaFX - getScene() returns null

javanullpointerexceptionjavafx-8

提问by The_Dude

I just started using JavaFX Scene Builder to build a small application.

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

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)':

它由属于“login.fxml”的控制器类“Login.java”组成,其中通过名为“registrationClicked(ActionEvent event)”的方法加载FXML文件“registrierung.fxml”:

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:

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

@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.

然而,'getScene()' 总是会导致 NullPointerException。两个 FXML 文件的控制器类都在 Scene Builder 中进行了调整。

This is how I set up the rood node in 'registrierung.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">

What am I doing wrong?

我究竟做错了什么?

采纳答案by The_Dude

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!

这会奏效!

回答by purring pigeon

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.

希望这可以帮助。

回答by Holgi P

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:

实现 Initializable 接口对我不起作用(Java 8)。方法 getScene() 总是为我返回 null。所以我不得不做以下事情:

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
}