Java FX Stage class 中的 showandwait() 和 show() 有什么区别?

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

我查看了文档,但我仍然不明白第一个方法在等待什么,这对舞台有何影响。一些有用的例子可以证明两者之间的区别,我们将不胜感激。

考虑以下示例

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");
    }
}

如果你执行这个版本,inner.show()会立即显示第二阶段和return,所以你会在控制台上看到Done

如果您将 inner.show() 替换为 inner.showAndWait(),该方法将不会 return 并且 等待 直到您关闭内部阶段才能继续。当您关闭内部阶段时,您才会在控制台上看到“完成”。

showAndWait() 阻止执行 直到阶段关闭。 show() returns 立即。

要查看差异,运行 下面的演示。通过调用 show(),当前值取自文本字段,而不是等待用户键入内容并关闭 window。使用 showAndWait(),如果您在文本字段中键入并关闭 window,则会显示您键入的文本。

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);
    }

}