JavaFX2 : Closing a stage (substage) from within itself


Question

I am new to JavaFx and I am creating an application and was in need of something similar to JDialog that was offered while using swing components. I solved that by creating new stage, but now I need a way to close the new stage from within itself by clicking a button. (yes, the x button works too, but wanted it on button as well). To describe the situation: 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 control class again. There is a picture, a text area and a button, and I want that button to close the new stage that is the aboutBox from within the AboutBox.java class so to speak.

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?

Thanks in advance for your advices.

1
9
7/13/2012 10:34:49 AM

Accepted 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();
  }
}
22
7/13/2012 6:23:55 PM

In JavaFX 2.1, you have few choices. The way like in jewelsea's answer or the way what you have done already or modified version of it like

public class AboutBox extends Stage {

    public AboutBox() throws Exception {
        initModality(Modality.APPLICATION_MODAL);
        Button btn = new Button("Close");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent arg0) {
                close();
            }
        });

        // Load content via
        // EITHER

        Parent root = FXMLLoader.load(getClass().getResource("AboutPage.fxml"));
        setScene(new Scene(VBoxBuilder.create().children(root, btn).build()));

        // OR

        Scene aboutScene = new Scene(VBoxBuilder.create().children(new Text("About me"), btn).alignment(Pos.CENTER).padding(new Insets(10)).build());
        setScene(aboutScene);

        // If your about page is not so complex. no need FXML so its Controller class too.
    }
}

with usage like

new AboutBox().show();

in menu item action event handler.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon