Marko Gresak
Marko Gresak

Reputation: 8217

JavaFX global scene variable unexpectedly changed to null

I want to make an application in javaFX 2 which opens as a smaller login window, then, when you put in correct data, it takes you to bigger main window. Both are designed in fxml and events are handled within java code.

Yes, I know, it is almost the same as the application in samples and I've tried to do what I want and it worked there.

Now, when I did the same in my project, I hit a problem when I want to change the value of stage.

As you can see in the code below, I have global variable and I set the value of primaryStage in start method to it. Just as a test, I print it out at end of start method and the value is set.

Then, when I try to use it when button is clicked(method buttonClick), the value of stage variable is null, therefore I cannot use it to resize window or anything else.

My question is why is stage variable value reseted despite that I don't use change anything between the two prints?

This code is sample of what I've tried, I've just cut out all code which is not crucial to understand how my application works.

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

Upvotes: 1

Views: 3889

Answers (1)

Uluk Biy
Uluk Biy

Reputation: 49215

Although it is not clear by whom and where the buttonClick action method is called, I pressume it is a login button's action in Login.fxml. Also I assume you have defined the App (a.k.a PrijavnoOkno) as a controller of this Login.fxml.
According to these assumptions, there are 2 instances of App.class:
one created when the app starts up and where the stage variable is assigned with primary stage in start() method,
and another instance created by FXMLLoader (while loading Login.fxml) and where the stage variable is not assigned and thus NPE.
One of the right ways can be, create a new Controller class for Login.fxml, call your login action in it. Access the global stage (by making it static in App) from there.

Upvotes: 2

Related Questions