JavaFX全局场景变量意外更改为null

时间:2012-08-13 11:11:54

标签: nullpointerexception global-variables javafx-2 fxml

我想在javaFX 2中创建一个应用程序,它作为一个较小的登录窗口打开,然后,当你输入正确的数据时,它会带你到更大的主窗口。两者都是用fxml设计的,事件是在java代码中处理的。

是的,我知道,它与样品中的应用程序几乎相同,我尝试做我想做的事情并且在那里工作。

现在,当我在项目中做同样的事情时,当我想改变舞台的价值时,我遇到了一个问题。

正如您在下面的代码中看到的,我有全局变量,我在start方法中将primaryStage的值设置为它。就像测试一样,我在start方法结束时将其打印出来并设置值。

然后,当我在单击按钮时尝试使用它时(方法buttonClick),stage变量的值为null,因此我无法使用它来调整窗口或其他任何内容。

我的问题是,尽管我在两张照片之间没有使用任何更改,但为什么阶段变量值会被重置?

这段代码是我尝试过的示例,我刚刚删除了所有代码,这些代码对于理解我的应用程序的工作原理并不重要。

public class App extends Application {

    private Stage stage;
    @FXML
    private AnchorPane pane;

    @Override
    public void start(Stage primaryStage) {
        try {
            stage = primaryStage; // Set the value of primaryStage to stage
            primaryStage.setScene(new Scene(openScene("Login"))); // Load Login window
            primaryStage.show(); // Show the scene
        } catch (IOException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println(stage);// <-- Here it has the value of primaryStage obviously
    }

    @FXML
    void buttonClick(ActionEvent event) throws IOException {
    // Note that even if I try to print here, the value of stage is still
    // null, so the code doesn't affect it
    // Also, this loads what I want, I just can't change the size.
        try{
           pane.getChildren().clear(); // Clear currently displayed content
           pane.getChildren().add(openScene("MainScene")); // Display new content
           System.out.println(stage); // <-- Here, output is null, but I don't know why
           stage.setWidth(500); // This line throws error because stage = null
        } catch (IOException ex) {
           Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        }

    }  

    public Parent openScene(String name) throws IOException {
        //Code from FXML login example
        Parent parent = (Parent) FXMLLoader.load(PrijavnoOkno.class.getResource(name
                + ".fxml"), null, new JavaFXBuilderFactory());
        return parent;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

1 个答案:

答案 0 :(得分:2)

虽然不清楚调用buttonClick操作方法的对象和位置,但我在Login.fxml中按下它是一个登录按钮的操作。此外,我假设您已将App(a.k.a PrijavnoOkno)定义为此Login.fxml的控制器。
根据这些假设,App.class有2个实例:
在应用程序启动时创建的一个,以及在start()方法中为舞台变量分配主要阶段的地方,
和FXMLLoader创建的另一个实例(在加载Login.fxml时)和未分配阶段变量的情况,因此NPE。
其中一种正确的方法是,为Login.fxml创建一个新的Controller类,在其中调用您的登录操作。从那里访问全局阶段(通过在App中使其静态)。