当前位置: 首页 > 知识库问答 >
问题:

绑定StringProperty时出现多线程错误

温成济
2023-03-14

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

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

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

现在,在Updater线程中,我更新了这些Properties。使用DoubleProperty这很好,并且ProgressBar完美地显示了进度。但是,使用状态更新Label(这是StringProperty中的文本)会引发错误:java.lang.IllegalStateException:不在FX应用程序线程上;当前线程=线程-9

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

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

共有1个答案

尉迟远
2023-03-14

无论是否引发异常,从FX应用程序线程以外的线程调用导致UI更改的代码都是错误的。如果违反此规则,FX toolkit会尽最大努力引发异常,但在某些情况下,对性能的影响太大,无法执行检查。如果创建这些绑定,则必须在FX应用程序线程上执行对已绑定属性的任何后续更改。一、 例如,如果在后台线程中运行,则必须使用以下代码更改属性:

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

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

由于您可能不希望服务代码绑定到JavaFX(通过平台类),因此可以考虑使用侦听器而不是绑定,并计划从侦听器进行更新:

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

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

 类似资料:
  • 问题内容: 我有一个关于多线程和StringProperty绑定的问题。 我有一个类,其中包含,该类使用服务器上的更改更新缓存。现在,我想用文本和进度百分比(在JavaFX 中为和)通知用户。我使用公共静态和对于这一点,这是在定义类。我只是这样绑定它: 现在,在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秒打印一条不同的消息。这两个线程需要在不修改时间打印线程的情况下完成。 所有这些线程都需要共享每秒更新的计数器对象。每次更新计数器对象时,时间打印