绑定StringProperty时出现multithreading错误
我有一个关于multithreading和StringProperty绑定的问题。
我有一个类CacheManager
,它包含一个Thread
,它根据服务器上的更改更新我的缓存。 现在,我想通知文本和进度的百分比(这是JavaFX中的Label
和ProgressBar
)。 我DoubleProperty
使用公共静态DoubleProperty
和StringProperty
,它们在CacheManager
类中定义。 我只是像这样绑定它:
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 = Thread-9
java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-9
现在,我的问题是: 为什么DoubleProperty
工作得很好,而StringProperty
会抛出错误? 他们考虑multithreading有什么区别?
任何关于重新设计的想法也欢迎,非常感谢任何帮助!
调用导致从FX应用程序线程以外的线程更改UI的代码是错误的, 无论它是否抛出exception 。 如果您违反此规则,FX工具包会尽最大努力抛出exception,但在某些情况下,对性能的影响太大而无法执行检查。 如果创建这些绑定,则必须在FX应用程序线程上执行对您绑定的属性的任何后续更改。 即,如果您在后台线程中运行,则必须使用以下代码更改属性:
Platform.runLater(() -> CacheManager.progress.set(...));
和
Platform.runLater(() -> CacheManager.status.set(...));
由于您可能不希望将服务代码绑定到JavaFX(通过Platform
类),因此可以考虑使用侦听器而不是绑定,并从侦听器调度更新:
CacheManager.progress.addListener((obs, oldValue, newValue) -> Platform.runLater(() -> progressBar.setProgress(newValue.doubleValue()))); CacheManager.status.addListener((obs, oldStatus, newStatus) -> Platform.runLater(() -> someLabel.setText(newStatus)));
如果使用这些侦听器替换绑定,则可以自由更新任何线程上的属性。
- 如何强制JSON-lib的JSONObject.put(..)转义包含JSON的字符串?
- javax.crypto.IllegalBlockSizeException:解密时最后一个块不完整 – 解密加密的AES字符串
- 如果找不到实体,则为空对象
- Java文件编码转换
- 在JDBC中停止或终止长时间运行的查询
- 如何使字符串值在java中调用特定的现有JButton变量名?
- 由于jdwp错误,无法从IntelliJ IDEA运行项目
- 查看oracle app并获取:java.lang.ClassNotFoundException:oracle.forms.engine.Main
- 如何使用Apache POI为docx文件中的段落设置标题样式?