JavaFX - 在主舞台关闭时关闭任何其他舞台,但允许它们隐藏在主舞台后面

时间:2015-05-21 15:02:17

标签: java javafx window

我们说我正在创建第二个窗口的代码如下:

    stage.initModality(Modality.NONE);
    stage.initOwner(coreController.getStage());

如果我这样做,它将在我的主窗口关闭时关闭。

如果我评论stage.initOwner(coreController.getStage());,那么它就可以隐藏在主面板后面,但不会关闭。

当我杀死主舞台时,有没有办法让它关闭... 没有编写代码来跟踪创建的每个新窗口?到目前为止,似乎我唯一的选择是在列表中注册每个新窗口,当主窗口发出“关闭事件”时,我也会为所有其他窗口启动它。有没有办法做到这一点,我不必进入并将所有东西连接在一起?

编辑:我使用了Modality.NONE,因此窗口不会阻止任何事件,但我不知道这是否与问题相关。

编辑2:我希望在退出主窗口时关闭所有窗口(如果我可以拦截近距离事件并进行清理,那将是一个奖励。)

2 个答案:

答案 0 :(得分:4)

如果您只是想关闭所有子窗口,但是由于某些其他原因(例如您打开兄弟窗口等等)保持应用程序运行,那么我认为您必须按照自己的建议自行管理问题(保留一个窗口列表并单独调用hide()等)。

如果您实际上计划退出应用程序,那么您可以这样做:

mainWindow.setOnHidden(e -> Platform.exit());

这将导致JavaFX系统正常退出(这当然会导致其他每个窗口关闭)。

如果需要清理资源,可以覆盖应用程序子类中的stop()并清理该方法中的资源。通过stop()关闭应用程序时,系统会为您调用Platform.exit()(但请注意,如果您执行System.exit(...),则不会调用该应用程序。)

如果您需要在每个窗口的基础上清理资源,那么您可以在每个窗口中注册onHidden()个处理程序来执行此操作。请注意,如果您随后隐藏了show()相同的窗口实例,则表示您可能需要恢复这些资源。这个用例非常不典型。

这是一个准确的例子:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ExitOnMainWindowClose extends Application {

    @Override
    public void start(Stage primaryStage) {
        Button newWindowButton = new Button("New Window");
        newWindowButton.setOnAction(e -> showNewWindow());
        primaryStage.setScene(new Scene(new StackPane(newWindowButton), 120, 75));
        primaryStage.setOnHidden(e -> Platform.exit());
        primaryStage.show();
    }

    @Override
    public void stop() {
        System.out.println("Application-level cleanup...");
    }

    private void showNewWindow() {
        Stage stage = new Stage();
        stage.setScene(new Scene(new StackPane(new Label("New Window")), 180, 60));
        stage.setOnHidden(e -> System.out.println("Window-level cleanup..."));
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

答案 1 :(得分:0)

如果我正确理解了这个问题,你可以为主要关闭时需要关闭的每个阶段调用initOwner(mainStage)。

只需添加对Oracle文档的引用,就可以解释为什么initOwner(mainStage)不适合这种情况:

  

舞台可以选择拥有所有者窗口。当窗口是舞台的所有者时,它被称为该舞台的父级。关闭父窗口时,将关闭其所有后代窗口。应用于图标化的父窗口的相同链接行为。 舞台将始终位于其父窗口之上。必须在阶段可见之前初始化所有者。

来自:https://docs.oracle.com/javase/8/javafx/api/javafx/stage/Stage.html#initOwner-javafx.stage.Window-