当前位置: 首页 > 面试题库 >

绑定StringProperty时出现多线程错误

闻人伟
2023-03-14
问题内容

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

我有一个类CacheManager,其中包含Thread,该类使用服务器上的更改更新缓存。现在,我想用文本和进度百分比(在JavaFX
中为LabelProgressBar)通知用户。我使用公共静态DoublePropertyStringProperty对于这一点,这是在定义CacheManager类。我只是这样绑定它:

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

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

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

也欢迎任何关于重新设计的想法,我们将不胜感激!


问题答案:

调用导致FX Application Thread以外的线程对UI进行更改的代码是错误的, 无论它是否引发异常
。如果违反此规则,FX工具箱将尽最大努力抛出异常,但是在某些情况下,对性能的影响太大,无法执行检查。如果创建这些绑定,则 必须 在FX
Application Thread上执行对绑定到的属性的任何后续更改。即,如果您在后台线程中运行,则 必须 使用以下代码更改属性:

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)));

如果用这些侦听器替换绑定,则可以随意更新任何线程上的属性。



 类似资料:
  • 我有一个关于多线程和StringProperty绑定的问题。 我有一个类CacheManager,它包含一个线程,可以根据服务器上的更改更新缓存。现在,我想用文本和进度百分比(JavaFX中的标签和进度条)通知用户。为此,我使用公共静态的DoubleProperty和StringProperty,它们是在CacheManager类中定义的。我只是这样装订: 现在,在Updater线程中,我更新了这

  • 我有一个名为的单例。它负责在菜单中显示正确的文本。它会动态更新。 我有一个fxml文件,但是MenuText不能有对它的引用。(这将与MVVM体系结构风格相矛盾) 这是正确的做法吗?我现在有了一个MenuFactory,它也是在JavaFX方法中创建的。它设置场景的父级。 start()mehtod如下所示: 这让它变得更加复杂,我不确定这是否正确。此外,我仍然不知道如何设置fxml文件中的菜单文

  • 我试图在我的Mac上安装Bundler宝石。使用命令:我得到以下错误: 这显然是一个服务器问题,但我该如何着手解决这个问题呢<代码>gem更新--系统当前是最新的。是否有其他方式获得Bundler?

  • 本文向大家介绍java实现多线程之定时器任务,包括了java实现多线程之定时器任务的使用技巧和注意事项,需要的朋友参考一下 在Java中Timer是java.util包中的一个工具类,提供了定时器的功能。我们可以创建一个Timer对象,然后调用其schedule方法在某个特定的时间去执行一个特定的任务。并且你可以让其以特定频率一直执行某个任务,这个任务是用TimerTask来描述的,我们只需要将要

  • 我正在尝试编写一个简短的Java程序,它使用多个线程来创建计时器。当计时器达到7秒或15秒时,它将打印一条消息。 我需要创建一个共享计数器。时间打印线程将计数器递增1,并从执行开始每秒打印其值。一个消息打印线程每15秒打印一条消息,另一个消息打印线程每7秒打印一条不同的消息。这两个线程需要在不修改时间打印线程的情况下完成。 所有这些线程都需要共享每秒更新的计数器对象。每次更新计数器对象时,时间打印