【问题标题】:Why does my JavaFX have this program flow problem?为什么我的 JavaFX 会出现这个程序流程问题?
【发布时间】:2020-01-24 00:57:17
【问题描述】:

使用 JavaFX 和 FXML 我试图显示一个包含一些基本信息的屏幕,然后当 HTTP 调用返回时,更新该屏幕。相反,在调用返回之前,屏幕根本不会显示。下面是问题的最小案例测试,延迟意味着模拟 HTTP 调用。

我希望屏幕显示出来,更新第一个标签,延迟 10 秒,然后更新第二个标签。相反,直到延迟完成后才会显示屏幕,无论我把延迟放在哪里都会发生这种情况。我希望我忽略了一些简单的事情,而不是创建多个线程来做如此简单的事情。以下是我认为任何能够回答问题的人的足够代码。如果需要,我可以包含更多代码。

@Override
public void start(Stage stage) throws IOException {

    this.stage = stage;
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(App.class.getResource("primary.fxml"));
    anchroot = (AnchorPane) loader.load();
    // Show the scene containing the root layout.
    Scene scene = new Scene(anchroot);
    stage.setScene(scene);
    // Give the controller access to the main app.
    PrimaryController controller = loader.getController();
    controller.setMainApp(this);
    stage.show();

    //change the first label
    controller.setLabel0();

    //timer to simulate IO
    try {
        TimeUnit.SECONDS.sleep(10);
    } catch (Exception e) {
        e.printStackTrace();
    }

    //try to change the second label 10 sec later
    controller.setLabel1();

}

【问题讨论】:

  • 你能显示controller.setLabel0()controller.setLabel1() 的代码吗?还有一个更严重的问题是您在主线程上执行 IO 操作,这可能与您的问题有关。使用 JavaFX 提供的 Service 类,创建多个线程比您想象的要容易
  • 您必须从不阻塞或在 JavaFX 应用程序线程上执行长时间运行的工作。该线程负责更新 UI 状态、处理用户生成的事件以及调度渲染“脉冲”。如果你垄断或阻塞了 FX 线程,那么它就不能做任何这些事情,你最终会得到一个无响应(即冻结)的 UI。您需要将任何阻塞或长时间运行的工作移至后台线程,然后将任何结果发布回 FX 线程以更新 UI — 请参阅Concurrency in JavaFX

标签: java maven javafx netbeans fxml


【解决方案1】:

调用TimeUnit.SECONDS.sleep(10); 将使JavaFX 线程阻塞10 秒。在这种情况下,您将无法看到 GUI 线程中的任何更改,直到休眠期结束。在 JavaFX 中,您可以使用 Timeline 在一段时间后进行更新:

controller.setLabel0();
new Timeline(new KeyFrame(Duration.seconds(10), event -> controller.setLabel1())).play();

【讨论】:

    猜你喜欢
    • 2015-12-09
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 2021-11-28
    • 2019-04-17
    • 1970-01-01
    相关资源
    最近更新 更多