java - 如何在线程和 GUI 之间进行通信

标签 java multithreading kotlin javafx

目前我使用 Kotlin 和 Java 开发桌面应用程序,GUI 是使用 JavaFX 制作的。 我有几个基本的 UDP 服务器(Kotlin 线程)监听不同的端口以通过网络接收数据。连接工作正常。

我可以想到几种(或多或少复杂的)线程和 GUI Controller 之间通信的方法,但我想知道是否有某种默认方法,我根本不知道.

我正在寻找一种简单的方法,将“消息”从线程发送到 Controller ,以便更改标签上的某些文本或类似的内容。

最佳答案

使用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 反馈信息的要求,直接调用 runLater 可能是比使用 JavaFX 任务更合适的解决方案。

其他问题的答案

However binding might work in my case

如果未将调用包装在 Platform.runLater 调用中,请勿使用绑定(bind)、修改属性或从另一个线程触发更改监听器。

绑定(bind)和更改监听器不适用于多线程环境(例如,如果您同时修改不同线程上的绑定(bind)或更改监听器,结果可能是不可预测的)。另外,如果您的绑定(bind)或更改监听器最终触发 JavaFX 应用程序线程对 Activity 场景图的更改,则结果可能再次无法预测,因为场景图并非设计用于以这种方式使用。

At the moment I don't get how I should use the runLater() since I have no access to the relevant GUI elements from the thread class.

一些不同的选项:

  1. 为线程类提供对 GUI 元素的访问,以便它可以在 runLater 调用中修改它们(这是您的设计修改)或
  2. 让线程类调用另一个类上的方法(通过 runLater),该类确实了解 GUI 元素并可以进行适当的更改或
  3. 使用具有可观察属性的共享模型类,您已将其附加到已建立绑定(bind)或更改监听器的 Controller 类,以根据属性的更改来更新 UI。从你的线程中你应该 read (有关从 GUI 线程与另一个线程通信的方法,请参阅链接)并使用 runLater 将可观察属性写入共享模型类。

正如您所见,在所有情况下,最终都会使用 runLater 来安排涉及稍后在 JavaFX 线程上运行的 GUI 的工作,以强制系统内的线程安全。在所有情况下,如果您无法直接访问 GUI 元素,则需要与可以直接访问 GUI 元素的东西进行通信,以便它可以代表您进行任何必要的修改。

关于java - 如何在线程和 GUI 之间进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59379148/

相关文章:

java - 从 HttpURLConnection 获取数据作为文本抛出 javax.net.ssl.SSLHandshakeException for SourceForge.net

java - 取消部署 Java EE 应用程序时如何停止线程?

c# - 单声道 Thread.Sleep(int) 抛出 System.TypeLoadException

Android Kotlin 将微调器值传递给可变列表

java - 您如何配置 Session-Scoped bean 以能够访问来自请求和其他服务的信息?

java - 在 Splash fragment 之后从 ActionBarActivity 中隐藏 ActionBar

Java Thread - 制作时钟和自己的时钟

kotlin - 如何使用成员引用在 Kotlin 中创建属性的分层路径

android - DiffUtil 和 registerAdapterDataObserver

java - 多态性细胞写作