JavaFX - How to focus on one stage

Mohamed Benmahdjoub picture Mohamed Benmahdjoub · Apr 8, 2015 · Viewed 7k times · Source

My application has a main app Stage that opens a 2nd window from it. I want to focus on only one stage.

I have 2 issues which I want to be resolved :

1 - How can I put the focus on only the second Stage (a fileChooser OpenDialog)? i.e. I can't switch to the main app Stage until user has clicked on Open or Cancel.

2 - How can I oblige the user to close the 2nd Stage before he can close the main Stage?

Right now, I can close the main window while the 2nd stage(OpenDialog) is still running.

Thanks.

Answer

ItachiUchiha picture ItachiUchiha · Apr 8, 2015

You can use a combination of Modality and Ownership of stages.

subStage.initOwner(stage) -> Makes sure that the substage moves along with its owner.

subStage.initModality(Modality.WINDOW_MODAL) -> Makes sure that substage blocks input events from being delivered to all windows from its owner (parent) to its root.

You can also use Modality.APPLICATION_MODAL if you want to block input events to all windows from the same application, except for those from its child hierarchy.

Dialog follows modal and blocking fashion by default. The default modality for Dialog is Modality.APPLICATION_MODAL and you can add initOwner(...) to it.

Note: You cannot apply the above stated rules to FileChooser. However, you can use showOpenDialog(Window ownerWindow) for it.

fileChooser.showOpenDialog(stage);

Complete Example

import javafx.application.Application;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class Main extends Application {

    @Override public void start(Stage stage) {

        stage.setTitle("Main Stage");
        stage.setWidth(500);
        stage.setHeight(500);
        stage.show();

        Stage subStage = new Stage();
        subStage.setTitle("Sub Stage");
        subStage.setWidth(250);
        subStage.setHeight(250);
        subStage.initOwner(stage);
        subStage.initModality(Modality.WINDOW_MODAL);
        subStage.show();
    }

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