如何让我的程序等到 JavaFX window 关闭后再继续?
How can I get make my program wait until JavaFX window has been closed before continuing?
我有一个显示结果条形图的程序。我想等到用户关闭条形图以继续下一行代码,询问他们是否要为图表输入新信息。
Scene scene = BarGraph.getBarChart();
primaryStage.setScene(scene);
primaryStage.setTitle("Bar Chart");
primaryStage.show();
repeat = JOptionPane.showConfirmDialog(null, "Would you like to enter another number?");
发生的情况是条形图的场景将打开,但不会显示任何内容,并立即弹出 JOptionPane 并提出问题。如果我点击否,则显示图表,但程序结束。如果我点击“是”,程序会循环回到之前的对话框 windows,但不会显示图表,直到另一个对话框结束。
我想等到用户关闭条形图后再提示他们。在这一点上我很沮丧,我什至会人为地暂停一下,比如 wait(5000) 之类的,尽管我也无法让它工作。
我已经阅读了这么多,但还没有找到真正有效的解决方案。最接近的问题是:JavaFX wait till stage has been closed
据我了解,我实际上无法让程序等待,但可以设置在 window 关闭后发生的操作。但是按照那里的建议只是导致舞台打开然后立即关闭。我已经找到了其他几个兔子洞,但无济于事。
尝试使用 Stage.showAndWait()
而不是 Stage.show()
。
The show()
method returns immediately regardless of the modality of the stage. Use the showAndWait()
method if you need to block the caller until the modal stage is hidden (closed). The modality must be initialized before the stage is made visible.
,您需要先创建另一个舞台,因为在初级舞台上使用它会导致错误。
This method must not be called on the primary stage or on a stage that is already visible.
与所有 UI 工具包一样,JavaFX 是事件驱动的。这意味着您通常不会编写代码来循环执行 UI 任务,而是编写响应用户事件(包括关闭 window)的事件处理程序。这基本上是您在问题中正确总结的内容:
From what I read there is that I can't actually cause the program to wait, but can set actions to occur once the window is closed.
您应该通过创建警报(不要在 JavaFX 应用程序中使用 Swing JOptionPane
)并向初级阶段和警报注册 onHidden
侦听器来解决此问题。初级阶段的 onHidden
处理程序将显示警报。如果用户选择 "Yes",警报的 onHidden
处理程序将显示初级阶段(可能首先重置一些数据)。类似于:
Scene scene = BarGraph.getBarChart();
primaryStage.setScene(scene);
primaryStage.setTitle("Bar Chart");
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO);
alert.setContentText("Would you like to enter another number?");
// when alert closes, if user chose "YES", reshow the primary stage:
alert.setOnHidden(e -> {
if (alert.getResult() == ButtonType.YES) {
primaryStage.show();
}
});
// when the primary stage is closed, show the alert asking if the user
// wants to show another chart:
primaryStage.setOnHidden(e -> alert.show());
primaryStage.show();
这是一个简化的(即没有条形图)但完整的示例:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ReshowStageAlert extends Application {
@Override
public void start(Stage primaryStage) {
VBox root = new VBox(5, new Label("Enter a number"), new TextField());
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO);
alert.setContentText("Would you like to enter another number?");
alert.setOnHidden(e -> {
if (alert.getResult() == ButtonType.YES) {
primaryStage.show();
}
});
primaryStage.setOnHidden(e -> alert.show());
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我有一个显示结果条形图的程序。我想等到用户关闭条形图以继续下一行代码,询问他们是否要为图表输入新信息。
Scene scene = BarGraph.getBarChart();
primaryStage.setScene(scene);
primaryStage.setTitle("Bar Chart");
primaryStage.show();
repeat = JOptionPane.showConfirmDialog(null, "Would you like to enter another number?");
发生的情况是条形图的场景将打开,但不会显示任何内容,并立即弹出 JOptionPane 并提出问题。如果我点击否,则显示图表,但程序结束。如果我点击“是”,程序会循环回到之前的对话框 windows,但不会显示图表,直到另一个对话框结束。
我想等到用户关闭条形图后再提示他们。在这一点上我很沮丧,我什至会人为地暂停一下,比如 wait(5000) 之类的,尽管我也无法让它工作。
我已经阅读了这么多,但还没有找到真正有效的解决方案。最接近的问题是:JavaFX wait till stage has been closed
据我了解,我实际上无法让程序等待,但可以设置在 window 关闭后发生的操作。但是按照那里的建议只是导致舞台打开然后立即关闭。我已经找到了其他几个兔子洞,但无济于事。
尝试使用 Stage.showAndWait()
而不是 Stage.show()
。
The
show()
method returns immediately regardless of the modality of the stage. Use theshowAndWait()
method if you need to block the caller until the modal stage is hidden (closed). The modality must be initialized before the stage is made visible.
This method must not be called on the primary stage or on a stage that is already visible.
与所有 UI 工具包一样,JavaFX 是事件驱动的。这意味着您通常不会编写代码来循环执行 UI 任务,而是编写响应用户事件(包括关闭 window)的事件处理程序。这基本上是您在问题中正确总结的内容:
From what I read there is that I can't actually cause the program to wait, but can set actions to occur once the window is closed.
您应该通过创建警报(不要在 JavaFX 应用程序中使用 Swing JOptionPane
)并向初级阶段和警报注册 onHidden
侦听器来解决此问题。初级阶段的 onHidden
处理程序将显示警报。如果用户选择 "Yes",警报的 onHidden
处理程序将显示初级阶段(可能首先重置一些数据)。类似于:
Scene scene = BarGraph.getBarChart();
primaryStage.setScene(scene);
primaryStage.setTitle("Bar Chart");
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO);
alert.setContentText("Would you like to enter another number?");
// when alert closes, if user chose "YES", reshow the primary stage:
alert.setOnHidden(e -> {
if (alert.getResult() == ButtonType.YES) {
primaryStage.show();
}
});
// when the primary stage is closed, show the alert asking if the user
// wants to show another chart:
primaryStage.setOnHidden(e -> alert.show());
primaryStage.show();
这是一个简化的(即没有条形图)但完整的示例:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ReshowStageAlert extends Application {
@Override
public void start(Stage primaryStage) {
VBox root = new VBox(5, new Label("Enter a number"), new TextField());
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO);
alert.setContentText("Would you like to enter another number?");
alert.setOnHidden(e -> {
if (alert.getResult() == ButtonType.YES) {
primaryStage.show();
}
});
primaryStage.setOnHidden(e -> alert.show());
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}