Closing a Stage from within its controller

javafxjavafx-2user interface

I need a way to close a Stage from within itself by clicking a Button.

I have a main class from which I create the main stage with a scene. I use FXML for that.

public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("Builder.fxml"));
    stage.setTitle("Ring of Power - Builder");
    stage.setScene(new Scene(root));
    stage.setMinHeight(600.0);
    stage.setMinWidth(800.0);
    stage.setHeight(600);
    stage.setWidth(800);
    stage.centerOnScreen();
    stage.show();
}

Now in the main window that appears I have all the control items and menus and stuff, made through FXML and appropriate control class. That's the part where I decided to include the About info in the Help menu. So I have an event going on when the menu Help – About is activated, like this:

@FXML
private void menuHelpAbout(ActionEvent event) throws IOException{
    Parent root2 = FXMLLoader.load(getClass().getResource("AboutBox.fxml"));
    Stage aboutBox=new Stage();
    aboutBox.setScene(new Scene(root2));
    aboutBox.centerOnScreen();
    aboutBox.setTitle("About Box");
    aboutBox.setResizable(false);
    aboutBox.initModality(Modality.APPLICATION_MODAL); 
    aboutBox.show();
}

As seen the About Box window is created via FXML with a controller. I want to add a Button to close the new stage from within the controller.

The only way I found myself to be able to do this, was to define a
public static Stage aboutBox;
inside the Builder.java class and reference to that one from within the AboutBox.java in method that handles the action event on the closing button. But somehow it doesn't feel exactly clean and right. Is there any better way?

Best Answer

You can derive the stage to be closed from the event passed to the event handler.

new EventHandler<ActionEvent>() {
  @Override public void handle(ActionEvent actionEvent) {
    // take some action
    ...
    // close the dialog.
    Node  source = (Node)  actionEvent.getSource(); 
    Stage stage  = (Stage) source.getScene().getWindow();
    stage.close();
  }
}
Related Topic