如何让多个 Jframes 在 Java 中使用来自同一个线程的数据?

How can I make multiple Jframes consume data from the same Thread in Java?

我有一个程序必须输出体重秤的数据。它使用线程从 rs232 源不断读取数据,并且必须以图形方式输出数据。用户可以根据需要打开和关闭任意数量的 Jframes,并且所有 Jframes 都必须显示从 JTextArea 中的 rs232 读取的相同数据。我该如何处理? 非常感谢您。

首先,创建一个框架class extends JFrame,并创建一个从rs232接收数据的方法。然后这个 class 的每个对象都可以使用该方法获取数据。 您可以通过创建 class.

的一个对象来创建一帧

您可以通过多种方式解决此问题

The user can open and close as many Jframes as it wishes and all must show the same data that is read from the rs232

如果您只对实时结果或历史结果感兴趣,这就提出了一个问题。为了争论,我只关注实时结果。

基本上你需要从一个class开始,它负责实际从端口读取数据。 class 应该只做两件事:

  1. 读取数据
  2. 读取新数据时生成事件

为什么?因为之后您想要实现的任何附加功能(例如将数据写入数据库或出于某种原因缓存结果)都可以稍后添加,只需监视生成的事件即可。

接下来,您需要定义一个interface,它描述了观察者为了能够接收事件而将实施的契约

public interface ScaleDataSourceListener {
    public void scaleDataUpdated(ScaleDataSourceEvent evt);
}

您还可以添加连接事件 (connect/disconnect) 或其他可能很重要的事件,但我已保持简单。

ScaleDataSourceEvent 将是一个简单的 interface,它描述了事件的数据

public interface ScaleDataSourceEvent {
    public ScaleDataSource getSource();
    public double data();
}

例如(我喜欢接口,它们描述了预期的合同,定义了责任并限制了其他人在收到实现该接口的对象实例时可以做什么,但我就是这样)

然后您的数据源将允许观察者自行注册,以便收到有关它生成的事件的通知...

public interface ScaleDataSource ... {
    //...
    public void addDataSourceListener(ScaleDataSourceListener listener);
    public void removeDataSourceListener(ScaleDataSourceListener listener);
}

(我假设数据源将能够做其他事情,但我把它留给你来填写,再次强调,我更喜欢尽可能使用接口,这不是你的设计限制;))

因此,当从端口读取数据时,它会生成一个新事件并通知所有已注册的侦听器。

现在,Swing 不是线程安全的,这意味着,您不应该从事件调度线程以外的任何线程更新 UI。

对于您的情况,最简单的解决方案可能是简单地使用 SwingUtilities.invokeLater 从数据源线程上下文移动到 EDT。

基本上,这是一个简单的Observer Pattern

您还需要考虑许多其他注意事项。即,框架是在与数据源相同的进程中打开的,还是数据源在它自己的独立进程中运行的。这会使过程复杂化,因为您需要某种 IPC 系统,可能使用套接字,但最重要的设计是相同的。

如果数据源读取数据的速度比您生成事件的速度快,会发生什么情况?您可能需要某种队列,其中数据源只是将数据转储到队列中,并且您有某种调度程序(在另一个线程上)读取它并调度事件。

阻塞队列有多种实现,可提供一定程度的线程安全性,请查看并发 API 了解更多详细信息。

...作为一些想法 ;)