Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何让多个JFrame使用Java中同一线程的数据?_Java_Multithreading_Swing_Thread Safety_Swingworker - Fatal编程技术网

如何让多个JFrame使用Java中同一线程的数据?

如何让多个JFrame使用Java中同一线程的数据?,java,multithreading,swing,thread-safety,swingworker,Java,Multithreading,Swing,Thread Safety,Swingworker,我有一个程序,必须输出加权秤的数据。它使用线程从rs232源连续读取数据,并且必须以图形方式输出数据。用户可以根据需要打开和关闭任意多个Jframes,并且所有Jframes都必须显示从JTextArea中的rs232读取的相同数据。我怎样才能做到这一点? 非常感谢您。首先,创建一个frame类扩展JFrame,并创建一个从rs232接收数据的方法。然后该类的每个对象都可以使用该方法获取数据。 您可以通过创建类的一个对象来创建一个帧。有许多方法可以解决此问题 用户可以根据需要打开和关闭任意多个J

我有一个程序,必须输出加权秤的数据。它使用线程从rs232源连续读取数据,并且必须以图形方式输出数据。用户可以根据需要打开和关闭任意多个Jframes,并且所有Jframes都必须显示从JTextArea中的rs232读取的相同数据。我怎样才能做到这一点?
非常感谢您。

首先,创建一个frame类扩展JFrame,并创建一个从rs232接收数据的方法。然后该类的每个对象都可以使用该方法获取数据。
您可以通过创建类的一个对象来创建一个帧。

有许多方法可以解决此问题

用户可以根据需要打开和关闭任意多个Jframes,并且所有Jframes都必须显示从rs232读取的相同数据

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

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

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

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

    public interface ScaleDataSourceListener {
        public void scaleDataUpdated(ScaleDataSourceEvent evt);
    }
    
    您还可以添加连接事件(连接/断开连接)或其他可能很重要的事件,但我一直保持简单

    ScaleDataSourceEvent
    将是一个简单的
    接口
    ,用于描述事件的数据

    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

    基本上,这是一个简单的问题

    你还需要考虑很多其他因素。也就是说,帧是在与数据源相同的进程中打开的,还是数据源在其自己的独立进程中运行。这使过程复杂化,因为您需要某种IPC系统,可能使用套接字,但覆盖设计是相同的

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

    有许多阻塞队列的实现,它们提供了一定级别的线程安全,请通过并发API了解更多详细信息


    。。。作为一些想法;)

    看一看观察者模式,本质上你的线程需要生成你的框架所侦听的事件,只是要注意swing不是线程安全的,什么是更线程安全的方法?谢谢你的回答@MadProgrammer你只需要知道你的“线程”将在它自己的上下文中生成事件,然后使用
    SwingUtilities.invokeLater
    SwingWorker
    等方法确保您对UI所做的任何更新都是在事件上下文中完成的。您的答案不正确,因为它没有回答OP面临的基本问题。请将您的答案与程序员进行比较,并检查质量差异。