当前,我正在使用Kotlin和Java开发桌面应用程序,GUI是使用JavaFX制作的。 我有几个基本的UDP服务器(Kotlin线程)正在侦听不同的端口,以通过网络接收数据。连接工作正常。
我可以想到几种(或多或少复杂的)线程与GUI控制器之间的通信方式,但是我想知道是否存在某种默认方法,我只是不知道
我正在寻找一种简单的方法,可以将“消息”从线程发送到控制器,以便更改标签上的某些文本或类似内容。
答案 0 :(得分:2)
使用Platform.runLater
不在JavaFX线程上时,请使用Platform.runLater
调用最终将更新GUI的方法。
这样做将安排包装在runLater
中的代码,以便稍后在JavaFX应用程序线程上执行。
由于JavaFX系统被设计为单线程系统,因此有必要使该系统一致地工作。
JavaFX中的更高级别的并发支持
JavaFX还使用higher level concurrency support之类的东西Task
,这些东西通过诸如updateMessage
之类的方法具有一定的通信支持。在Task的实现级别上,updateMessage
仅在内部使用Platform.runLater
,但在实现中包括一些其他优化措施,以使其使用起来简单高效。
通常,Tasks和Platform.runLater具有不同的重点(有时是互补的),请参阅Javafx: Difference between javafx.concurent and Platform.runLater?。
特别是,对于需要UDP服务器侦听多个端口并将信息反馈给GUI的要求,与使用JavaFX Task相比,直接调用runLater
是更合适的解决方案。
其他问题的答案
但是对于我而言,绑定可能有效
在未将调用包装在Platform.runLater
调用中的情况下,请勿使用绑定,修改属性或从另一个线程触发更改侦听器。
绑定和更改侦听器并非旨在在多线程环境中工作(例如,如果您同时修改绑定或更改不同线程上的侦听器,则结果可能无法预测)。另外,如果您的绑定或更改侦听器最终触发了JavaFX应用程序线程对活动场景图的更改,那么结果可能又是不可预测的,因为场景图并非旨在以这种方式使用。
由于我无法从线程类访问相关的GUI元素,因此目前我不知道如何使用runLater()。
一些不同的选项:
runLater
调用中进行修改(这是您的设计修改),或者runLater
),该类确实了解GUI元素,并且可以进行适当的更改,或者runLater
将可观察的属性写入共享模型类。如您所见,在所有情况下,最终runLater
都用于安排涉及GUI的工作,该工作稍后将在JavaFX线程上运行,以在系统内实施线程安全。而且在所有情况下,如果您无法直接访问GUI元素,则需要与进行通信的对象进行通信,以便它可以代表您进行任何必要的修改。