我正在编写一个 JavaFX 程序,它不会在
Stage.show()
函数中显示舞台 (start(Stage)
),而是同一类中的其他方法调用 Stage.show()
以在稍后显示舞台。如果我尝试多次调用任何调用 Stage.show()
的方法,程序将自行终止。
舞台/窗口的首次展示按预期工作,在我使用 ✕ 关闭窗口后程序正确进行。但是,如果我尝试再次调用
Stage.show()
,即使是使用相同的方法,舞台/窗口也会打开并立即关闭,从而终止整个程序。没有错误:我正在使用 Eclipse,退出代码为 0,表明程序成功完成。我不知道第二次有什么不同让程序认为它应该终止。
我的程序是由我内置的命令系统指挥的,命令系统在窗口打开期间暂停,否则窗口会崩溃。因此,除了 ✕ 之外,我没有其他关闭窗口的方法。
Stage.setonHidden()
重新启动我的命令系统。
对于为什么关闭和重新打开阶段可能导致整个程序终止的任何见解都将不胜感激。
这是我程序的精简版:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Example extends Application{
static BorderPane mainPane = new BorderPane();
static Scene scene;
static Stage stage;
public static void main(String[] args) {
launch(args);
}
public void start(Stage newStage) {
stage = newStage;
scene = new Scene(mainPane, 640, 700);
stage.setScene(scene);
stage.setOnHidden(e -> showBuild()); //Runs successfully when window is closed
showBuild();
}
public static void showBuild() {
stage.show(); //fails to show stage and terminates program when called a second time
}
}
这里有两个不同的问题。第一个(也是我最了解的一个)是默认情况下,JavaFX 平台将在最后一个窗口关闭时退出。您可以通过调用
来避免这种情况Platform.setImplicitExit(false);
在这种情况下,您需要显式调用
Platform.exit();
终止申请。
第二个似乎是时间问题。看起来
onHidden
事件处理程序在窗口正确关闭之前就已经关闭了。因此,您调用了stage.show()
,但随后关闭了底层本地对等窗口,导致该窗口不出现。这可能是一个错误。
一些解决方法:
在
Platform.runLater(...)
中包装调用,这将使调用在 FX 应用程序线程上排队,并且在挂起的事件处理程序完成之前不会调用它。这确保了对 stage.show()
的调用发生在窗口完全关闭之后。
public void start(Stage newStage) {
Platform.setImplicitExit(false);
stage = newStage;
scene = new Scene(mainPane, 640, 700);
stage.setScene(scene);
stage.setOnHidden(e -> Platform.runLater(Example::showBuild));
showBuild();
}
改用
showingProperty()
。这似乎只有在窗口完全关闭后才会改变。
public void start(Stage newStage) {
Platform.setImplicitExit(false);
stage = newStage;
scene = new Scene(mainPane, 640, 700);
stage.setScene(scene);
stage.showingProperty().addListener((obs, wasShowing, isNowShowing) -> {
if (! isNowShowing) {
showBuild();
}
});
showBuild();
}