我有一个显示结果条形图的程序。我想等到用户关闭条形图以继续下一行代码,询问他们是否要输入图表的新信息。
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问题。如果我没有,则显示图表,但程序结束。如果我点击是,程序将循环回到之前的对话框窗口,但不会显示图表,直到另一个对话框结束。
我想等到用户关闭条形图之后再等它。我在这一点上非常沮丧,我甚至做了一个人为的停顿,比如等待(5000)或其他什么,虽然我也无法让它工作。
我已经读了这么多,还没有找到真正有用的解决方案。最接近的问题是:JavaFX wait till stage has been closed
从我读到的内容中,我实际上无法让程序等待,但可以在窗口关闭后设置动作。但是根据这些建议,只是让舞台开启然后立即关闭。我已经在其他几个兔子洞里摔倒,但无济于事。
答案 0 :(得分:3)
尝试使用Stage.showAndWait()
代替Stage.show()
。
无论阶段的形式如何,
show()
方法都会立即返回。如果需要阻止调用者直到隐藏(关闭)模态阶段,请使用showAndWait()
方法。必须在阶段可见之前初始化模态。
As James_D points out,您需要先创建另一个阶段,因为在主阶段使用此阶段会导致错误。
不得在主舞台或已经可见的舞台上调用此方法。
答案 1 :(得分:2)
与所有UI工具包一样,JavaFX是事件驱动的。这意味着您通常不会编写代码来循环执行UI任务,而是编写响应用户事件的事件处理程序(包括关闭窗口)。这基本上是您在问题中正确总结的内容:
从我读到的内容中,我实际上无法使程序等待,但可以在窗口关闭后设置动作。
您应该通过创建警报(不要在JavaFX应用程序中使用Swing JOptionPane
)并向主要阶段和警报注册onHidden
侦听器来解决此问题。主阶段的onHidden
处理程序将显示警报。如果用户选择“是”,则警报的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);
}
}