首页 > 解决方案 > 显示窗口后运行逻辑

问题描述

我有一个小程序,它被另一个程序调用,下载/重命名一些文件,然后自行关闭。我想用一些简单的文本向用户展示进度。我的问题是,代码的逻辑在视图完全显示之前运行。窗口可见,但内容(在本例中为示例文本)不可见。

我已经尝试过 setOnShown()(如我的示例所示)或 setOnShowning()。我还尝试不使用 fxml 文件进行布局。但似乎没有任何效果。

public void start(Stage primaryStage) throws Exception {
        HBox root = new HBox();
        Text t = new Text();
        t.setText("sample Text");
        root.getChildren().add(t);
        Scene scene = new Scene(root, 300, 275);
        primaryStage.setTitle("FXML Welcome");
        primaryStage.setScene(scene);
        primaryStage.setOnShown(e -> {
            updaterLogic(); //do some work
        });
        primaryStage.show();

    }
    public static void main(String[] args) {
        launch(args);
    }
    public void updaterLogic(){
        try {
            Thread.sleep(10 * 1000);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

我希望在运行实际逻辑之前完成视图。我怎样才能归档这个?

标签: javafx

解决方案


要在显示窗口后执行某些操作,您可以:

  1. 监听一个WindowEvent.WINDOW_SHOWN事件。
    • Window.onShownWindow.addEventHandler
  2. 监听Window.showing属性并在它变为 时做出反应true
  3. 将代码放在调用show().
    • 但不是showAndWait()因为该方法在窗口关闭之前不会返回(并且在初级阶段调用是非法的)。

但是,如何做到这一点不是您的问题(您已经在使用onShown)。您的问题是由您如何执行“更新程序逻辑”引起的。在您updaterLogic()正在调用的方法中Thread.sleep(模拟工作)。由于事件处理程序在导致所述线程阻塞的JavaFX 应用程序线程上执行。当 FX 线程被阻塞时,它不能做任何与 GUI 相关的事情(例如布局传递、触发渲染脉冲、处理用户事件等)——因此没有渲染内容的冻结窗口。

将“更新程序逻辑”移动到后台线程,以便 FX 线程可以自由地完成其工作。有关 Java 中并发的一般信息,请参阅课程:并发java.util.concurrent包。有关 JavaFX 的详细信息,请参阅JavaFX 中的并发javafx.concurrent包和Platform.runLater(Runnable).

以下是 JavaFX 的两条黄金法则:

  1. 绝不能阻塞JavaFX 应用程序线程,也不能在其上执行长时间运行的工作。
  2. 必须始终访问和修改JavaFX 应用程序线程上的实时场景图。

    • 这由以下人员记录Node

      节点对象可以在任何线程上构建和修改,只要它们尚未附加到正在显示的窗口中的场景。应用程序必须将节点附加到这样的场景或在 JavaFX 应用程序线程上修改它们。

      注意:有些节点,​​如WebView,必须在FX线程上创建;这将酌情记录在案。


推荐阅读