Search code examples
javafxwindow

How to close a new popup window from Controller in JavaFX


I have Controller.java for Scene.fxml and ControllerSettings.java for WindowSettings.fxml. In Controller.java I create a new popup window (no dialog) with following method:

    @FXML
    public void handleSubmenuSettings(ActionEvent event) throws IOException {

        Stage stage; 
        Parent root;
        ControllerSettings controller;

        stage = new Stage();
        FXMLLoader loader = new FXMLLoader(getClass().getResource("WindowSettings.fxml"));
        root = (Parent) loader.load();
        controller = (ControllerSettings) loader.getController();
        stage.setScene(new Scene(root));

        stage.setTitle("Settings");
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.setResizable(false);
        stage.initOwner(submenuSettings.getScene().getWindow());
        stage.showAndWait();

        stage.setOnCloseRequest(e -> {
            e.consume();
            controller.saveSettings();
            stage.close();
        });
    }

I want to save the settings when closing the new popup window but that doesn't work with stage.setOnCloseRequest.


Solution

  • The showAndWait() method will block execution until the window has closed; i.e. subsequent statements will not be executed until after the window is closed. So you don't register the listener for the close request until after the window has been closed. Clearly, no request to close the window will occur after the window is closed, so your handler is never invoked.

    It's not really clear why you are using a close request handler anyway. Presumably you simply want to call controller.saveSettings() after the window closes. Since you are using showAndWait() you can just do:

    @FXML
    public void handleSubmenuSettings(ActionEvent event) throws IOException {
    
        Stage stage; 
        Parent root;
        ControllerSettings controller;
    
        stage = new Stage();
        FXMLLoader loader = new FXMLLoader(getClass().getResource("WindowSettings.fxml"));
        root = (Parent) loader.load();
        controller = (ControllerSettings) loader.getController();
        stage.setScene(new Scene(root));
    
        stage.setTitle("Settings");
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.setResizable(false);
        stage.initOwner(submenuSettings.getScene().getWindow());
        stage.showAndWait();
    
        controller.saveSettings();
    }