What is the difference between showandwait() and show() in Java FX Stage class?

Viewed 2633

I've looked at the documentation, but I still don't understand what the first method is waiting for and how does that affect the stage. Some helpful examples that demonstrate the difference between the two would be appreciated.

2 Answers

Consider the following example

public class Demo extends Application {
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage stage) {
        stage.setScene(new Scene(new Label("Demo")));
        stage.show();
        
        Stage inner = new Stage(){{setScene(new Scene(new Label("Inner"))); }};
        inner.show(); // Try replacing with showAndWait
        System.out.println("Done");
    }
}

If you execute this version, inner.show() will show the second stage and return immediately, so you will see Done on the console.

If you replace inner.show() with inner.showAndWait(), the method will not return and wait until you close the inner stage to continue. When you close the inner stage, only then you will see "Done" appear on the console.

showAndWait() blocks execution until the stage is closed. show() returns immediately.

To see the difference, run the following demo. With the call to show(), the current value is taken from the text field, instead of waiting for the user to type something and close the window. With showAndWait(), if you type in the text field and close the window, the text you typed is displayed.

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class ShowAndWaitDemo extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        
        // Show:
        VBox showDemo = new VBox(15);
        showDemo.getChildren().add(new Label("User entered:"));
        Label showResult = new Label(" ");
        showDemo.getChildren().add(showResult);
        Button show = new Button("Show");
        show.setOnAction(e -> {
            InputDialog dialog = new InputDialog();
            dialog.getStage().show();
            // This will execute immediately, so it'll give the wrong result:
            showResult.setText(dialog.getResult());
        });
        showDemo.getChildren().add(show);

        // Show and wait:
        VBox showAndWaitDemo = new VBox(15);
        showAndWaitDemo.getChildren().add(new Label("User entered:"));
        Label showAndWaitResult = new Label(" ");
        showAndWaitDemo.getChildren().add(showAndWaitResult);
        Button showAndWait = new Button("Show and Wait");
        showAndWait.setOnAction(e -> {
            InputDialog dialog = new InputDialog();
            dialog.getStage().showAndWait();
            // This will not execute until the stage is closed, so it will give the correct result:
            showAndWaitResult.setText(dialog.getResult());
        });
        showAndWaitDemo.getChildren().add(showAndWait);
    
        HBox root = new HBox(25, showDemo, showAndWaitDemo);
        root.setAlignment(Pos.CENTER);
        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    
    
    private static class InputDialog {
        private final Stage stage ;
        private final TextField input ;
        
        InputDialog() {
            input = new TextField("Enter value here:");
            Button close = new Button("Close");
            VBox root = new VBox(5);
            root.setAlignment(Pos.CENTER);
            root.getChildren().addAll(input, close);
            Scene scene = new Scene(root, 400, 400);
            stage = new Stage();
            stage.initModality(Modality.APPLICATION_MODAL);
            close.setOnAction(e -> stage.hide());
            stage.setScene(scene);
        }
        
        Stage getStage() {
            return stage ;
        }
        
        String getResult() {
            return input.getText();
        }
    }
    
    public static void main(String[] args) {
        Application.launch(args);
    }

}
Related