我有一个带有文本区域和保存按钮的GUI。当我按下后者时,文本被保存。这大约需要 2 秒钟。在保存过程中,按钮应该获得比保存前后更丰富的标题。
这是我的代码:
saveButton.setText("Saving...");
Util.print("Saving...");
Thread saveIt = new Thread(new Runnable() {
@Override public void run() {
Platform.runLater(() -> {
try {
Thread.sleep(2000);
} catch (Exception ex) {
Util.print(ex);
}
saveButton.setText("Saved!");
Util.print("Saved!");
});
}
});
saveIt.setDaemon(true);
saveIt.start();
发生什么:
按下按钮后,命令行上将生成以下输出:
Saving...
Saved!
命令行打印"正在保存..."直接在我点击保存按钮之后。按下 saveButton 2 秒后,命令行打印"已保存!",按钮标题更改为"已保存!
我所期望的:
命令行输出和按钮标题显示"正在保存..."直接在我单击保存按钮之后。2 秒后,标题将变为"已保存!
如何实现预期的行为?
提前非常感谢您的帮助。
PS:我知道很多人在从线程更改 GUI 元素时遇到过问题。我已经在StackOverflow和网络上读过一些关于它的文章,但这对我来说太难了。仅供参考,以下是我迄今为止尝试的一些事情,其中包括任务:
不断更新 Java FX 工作线程中的 UI
为什么我在 JavaFX 上得到 java.lang.IllegalStateException "不在 FX 应用程序线程上"?
javafx,从另一个线程更新UI
http://blog.axxg.de/javafx-ui-thread-update/
我不得不将 Thread.sleep() 部分从 Platform.runLater() 进程中移除。看起来 runLater() 必须尽可能少地工作负载。
Platform.runLater(() -> {
saveButton.setText("Saving...");
Util.print("Saving...");
});
Thread saveIt = new Thread(new Runnable() {
@Override public void run() {
try {
sleep(2000);
} catch (Exception ex) {
Util.print(ex);
}
Platform.runLater(() -> {
saveButton.setText("Saved!");
Util.print("Saved!");
});
}
});
saveIt.setDaemon(true);
saveIt.start();
尝试将你的第一个setText包装到Platform.runLater中,如下所示:
Platform.runLater(() -> {
saveButton.setText("Saving...");
});
对 JavaFX UI 组件所做的每个更改都必须使用 Platform.runLater 从 JavaFX 线程调用