Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.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
Java 如何与来自其他线程的事件分派线程或swing组件通信?_Java_Multithreading_Swing - Fatal编程技术网

Java 如何与来自其他线程的事件分派线程或swing组件通信?

Java 如何与来自其他线程的事件分派线程或swing组件通信?,java,multithreading,swing,Java,Multithreading,Swing,我知道Swing组件,应该从事件分派线程调用它们,但现在我开发了以事件线程为中心的测试应用程序,这意味着UI通过在事件调用时调用侦听器来定义程序流。但是我已经读到其他线程不应该与UI通信,因为它是不同步的 大多数书只是教如何使用单个组件,而不是如何使用 在真实的应用程序上下文中使用它们 如何将已完成或正在处理的线程状态更新为swing组件。 更新:如果我们将侦听器配置为在执行服务中调用作业工作线程如何以安全的方式更新UI组件。最安全的方法是使用 SwingUtilities.invokeLate

我知道Swing组件,应该从事件分派线程调用它们,但现在我开发了以事件线程为中心的测试应用程序,这意味着UI通过在事件调用时调用侦听器来定义程序流。但是我已经读到其他线程不应该与UI通信,因为它是不同步的

大多数书只是教如何使用单个组件,而不是如何使用 在真实的应用程序上下文中使用它们

如何将已完成或正在处理的线程状态更新为swing组件。


更新:如果我们将侦听器配置为在执行服务中调用作业工作线程如何以安全的方式更新UI组件。

最安全的方法是使用

SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
        });

内部运行方法您可以操作Swing组件

基本答案是调用
重新绘制


AWT/Swing背后的理念是,在任何时候,组件都可以显示、调整大小、移动等(通过代码或通过用户交互),提示需要重新绘制。因此,当您进行更新时,应该更新渲染将基于的
模型
。。。有时为了一致性需要在EDT上执行此操作,然后使用重新绘制来显示对模型的更改

EDT的唯一任务是调用处理程序。您可以与它“通信”的唯一方法是注册要调用的处理程序。(注意:
invokeLater(…)
方法只是注册EDT将立即调用的处理程序的一种方法。)

我读到其他线程不应该与UI通信,因为

不要从“通信”的角度来考虑它,而要从在共享对象上运行的线程的角度来考虑它。您应该说的是,“其他线程不应该在Swing对象上运行。”

其他线程可以对您的对象进行操作,然后当EDT调用对象的
paint(g)
方法时,您的对象可以在屏幕上显示其更新状态。

您可以。。。 使用
SwingUtilities.invokeLater
计划在将来某个时间在EDT上执行回调

这个问题是线程之间的数据同步,因为更新可能需要的数据可能不再与调用时相同

你可以。。。 使用
SwingWorker
。这提供了一种在后台线程和EDT之间同步数据更改的方法,因为数据被传递到
过程
方法,因此它可以在调用时对“相关”/“相关”数据进行操作,这减少了(部分)对UI可能需要的数据同步访问的需要

更新:如果我们将侦听器配置为在ExecutorService中调用作业,那么工作线程如何以安全的方式更新UI组件

SwingWorker
本身可与
ExecutorService
兼容,您可以向其添加
SwingWorker
的实例,非常简单;)


您可以查看一下,您不应该从SwingWorker内部修改swing组件。它们是独立的线程,因此您应该使用'SwingUtilities.invokeLater'@T.G not true:“事件分派线程:所有与Swing相关的活动都发生在此线程上。SwingWorker调用process和done()方法并通知此线程上的任何PropertyChangeListeners。”-from-当然,您不应该在“doInBackground”中这样做…是的,你说得对,我应该澄清我的意思是不要修改
doInBackground
中的内容。这在大多数情况下都很诱人,但必须通过EDT调用的方法来实现。当你必须在后台做一些事情时,你应该打电话给Swingutilities。我可以给你一个更简单的/noob版本的链接示例。你可以选择,你可以保持原样,永远看不到这个或其他问题的解决方案,或者你可以看一看,相对而言,已经链接的简单示例,其中包括一个完全可运行的示例,您可以运行和调试该示例,您还可以查看和学习一些新的东西,并作为开发人员成长。坦率地说,在线程方面,没有“simple/noob”版本