我正在开发一个具有几个TextField对象的应用程序,这些对象需要进行更新以反映关联的后端属性中的更改。该TextFields为不可编辑,只有后端可能会改变他们的内容。据我了解,正确的方法是在单独的线程上运行大量计算,以免阻塞UI。我使用javafx.concurrent.Task进行了此操作,并使用updateMessage()很好地将单个值传递回了JavaFX线程。但是,我需要多个值来更新,因为后端需要处理。由于后端值存储为JavaFX属性,因此我尝试将它们简单地绑定到textProperty每个GUI元素的,然后让绑定完成工作。但是,这不起作用。在运行了片刻之后,TextField即使后端任务仍在运行,s也会停止更新。没有例外。我还尝试使用Platform.runLater()来主动更新TextFields而不是绑定。这里的问题runLater()是计划任务的速度比平台运行任务的速度快,因此GUI变得迟钝,即使后端任务完成后,GUI也需要时间来“赶上”。但我的问题仍然存在。总结:我有一个对属性进行更改的后端,并且我希望这些更改出现在GUI上。后端是一种遗传算法,因此其操作可分为几代。我希望TextFields在两代之间至少刷新一次,即使这会延迟下一代。与GA快速运行相比,GUI的良好响应更为重要。如果我还没有解决这个问题,我可以发布一些代码示例。更新我按照James_D的建议设法做到了。为了解决后端必须等待控制台打印的问题,我实现了一种缓冲的控制台。它将要打印的字符串存储在中,StringBuffer并TextArea在flush()调用方法时将它们实际附加到。我使用AtomicBoolean来防止在刷新完成之前发生下一代操作,因为刷新是由Platform.runLater()可运行的操作完成的。另请注意,此解决方案的速度非常慢。
2 回答
忽然笑
TA贡献1806条经验 获得超5个赞
执行此操作的最佳方法是使用TaskJavaFx。到目前为止,这是我在JavaFx中更新UI控件时遇到的最好的技术。
Task task = new Task<Void>() {
@Override public Void run() {
static final int max = 1000000;
for (int i=1; i<=max; i++) {
updateProgress(i, max);
}
return null;
}
};
ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();
添加回答
举报
0/150
提交
取消