【发布时间】: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