显示窗口后运行逻辑

时间:2019-04-07 13:21:58

标签: javafx

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

我已经尝试过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();
        }
    }

我希望在运行实际逻辑之前完成视图。我该如何存档?

1 个答案:

答案 0 :(得分:0)

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

  1. 收听WindowEvent.WINDOW_SHOWN事件。
    • 请参见Window.onShownWindow.addEventHandler
  2. 收听Window.showing属性,并在更改为true时做出反应。
  3. 在调用show()之后放入代码。
    • 但是showAndWait()不会,因为该方法直到窗口关闭(在主级上调用是非法的)后才返回。

但是,这不是您的问题(您已经在使用onShown)。您的问题是由执行“更新程序逻辑”引起的。在updaterLogic()方法内部,您正在调用Thread.sleep(模拟工作)。由于事件处理程序是在导致该线程阻塞的 JavaFX Application Thread 上执行的。当FX线程被阻止时,它无法执行与GUI相关的任何操作(例如,布局传递,触发渲染脉冲,处理用户事件等),因此冻结的窗口将不显示任何内容。

将“更新逻辑”移动到后台线程上,以便FX线程可以自由执行其工作。有关Java并发的一般信息,请参见Lesson: Concurrencyjava.util.concurrent软件包。有关JavaFX的详细信息,请参见Concurrency in JavaFXjavafx.concurrent软件包和Platform.runLater(Runnable)

这是JavaFX的两个黄金法则:

  1. 绝不能禁止或在JavaFX Application Thread 上执行长时间运行的工作。
  2. 必须始终访问和修改 JavaFX Application Thread 上的实时场景图。

    • 这由Node记录:

        

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

      注意:必须在FX线程上创建某些节点,例如WebView