gpt4 book ai didi

java - 绑定(bind) StringProperty 时出现多线程错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:55:10 25 4
gpt4 key购买 nike

我有一个关于多线程和 StringProperty 绑定(bind)的问题。

我有一个 CacheManager 类,它包含一个 Thread,它使用服务器上的更改更新我的缓存。现在,我想用文本和进度百分比通知用户(在 JavaFX 中是 LabelProgressBar)。为此,我使用 public static DoublePropertyStringProperty,它们在 CacheManager 类中定义。我只是像这样绑定(bind)它:

progressBar.progressProperty().bind(CacheManager.progress);
someLabel.textProperty().bind(CacheManager.status);

现在,在 Updater 线程中,我更新了这些 Properties。使用 DoubleProperty 这工作得很好,并且 ProgressBar 完美地显示了进度。但是,使用状态(来自 StringProperty 的文本)更新 Label 会引发错误:java.lang.IllegalStateException: Not on FX application thread; currentThread = 线程 9

现在,我的问题是:为什么 DoubleProperty 工作正常,而 StringProperty 却抛出错误?考虑到多线程,它们之间有什么区别?

也欢迎任何关于重新设计的想法,非常感谢任何帮助!

最佳答案

从 FX 应用程序线程以外的线程调用导致 UI 更改的代码是错误的,无论它是否抛出异常。如果违反此规则,FX 工具包会尽最大努力抛出异常,但在某些情况下,对性能的影响太大而无法执行检查。如果您创建了这些绑定(bind),那么您绑定(bind)到的属性的任何后续更改都必须在 FX 应用程序线程上执行。也就是说,如果您在后台线程中运行,您必须使用如下代码更改属性:

Platform.runLater(() -> CacheManager.progress.set(...));

Platform.runLater(() -> CacheManager.status.set(...));

由于您可能不希望您的服务代码绑定(bind)到 JavaFX(通过 Platform 类),您可以考虑使用监听器而不是绑定(bind),并安排来自监听器的更新:

CacheManager.progress.addListener((obs, oldValue, newValue) -> 
Platform.runLater(() -> progressBar.setProgress(newValue.doubleValue())));
CacheManager.status.addListener((obs, oldStatus, newStatus) ->
Platform.runLater(() -> someLabel.setText(newStatus)));

如果您用这些监听器替换绑定(bind),那么您可以自由地更新任何线程上的属性。

关于java - 绑定(bind) StringProperty 时出现多线程错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30863205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com