简体   繁体   English

默认情况下,所有Swing组件都在EDT上运行吗?

[英]Do all Swing components run on the EDT by default?

I'm new to Java and after reading many articles about threads and swing I understood that all the invocations of Swing methods should be done on the EDT because Swing is not thread safe. 我是Java的新手,在阅读了很多关于线程和swing的文章之后,我明白所有Swing方法的调用都应该在EDT上完成,因为Swing不是线程安全的。 however, I already wrote a couple of quite long Swing applications before reading about the EDT. 但是,在阅读有关EDT之前,我已经编写了几个相当长的Swing应用程序。 and all of my applications ran quite fine. 我的所有应用程序都运行得很好。 So my question is were my Swing applications running on the EDT by default or were they running on a different thread and i was just lucky not to have any issues with them? 所以我的问题是我的Swing应用程序默认运行在EDT上,还是在不同的线程上运行,我很幸运,没有任何问题? Like for example if I add a JButton to a JPanel or JFrame, or if I simply call a JTextField's Field.setText() , will these operations be running on the EDT by default or no? 例如,如果我将JButton添加到JPanel或JFrame,或者我只是调用JTextField的Field.setText() ,默认情况下这些操作是否会在EDT上运行? and if the answer is no, then do I have to explicitly send all my Swing component's methods implementations to run on the EDT by invoking SwingUtilities.invokeLater() 如果答案是否定的,那么我是否必须通过调用SwingUtilities.invokeLater()显式发送我的所有Swing组件的方法实现以在EDT上运行

Thanks 谢谢

Remember objects don't live on threads, only execution of methods happens on a thread. 记住对象不在线程上,只在线程上执行方法。

All action emerging (through listeners) from swing components automatically run on the EDT. 来自swing组件的所有动作(通过听众)自动在EDT上运行。

For instance a button you click, the onClicked() function will already run on the EDT so you don't need to do anything. 例如,您单击的按钮, onClicked()函数将已在EDT上运行,因此您无需执行任何操作。

If you don't create any threads explicitly, your basic application will have a main thread and an EDT (and many other threads that you don't accidentally get your code executed on, until you start using extra frameworks). 如果你没有显式创建任何线程,你的基本应用程序将有一个主线程和一个EDT(以及许多其他线程,你不会意外地执行你的代码,直到你开始使用额外的框架)。

The thing you have to do manually is construct the GUI on the EDT. 你必须手动完成的事情是在EDT上构建GUI。 As you can see here this can be done in your main thread as follows: 正如您在此处所见这可以在主线程中完成,如下所示:

   SwingUtilities.invokeLater(new Runnable() { 
        public void run() {            
            MyWindow window = new MyWindow ();
            window.setVisible(true);
        }
    });

If you fail to use the EDT correctly. 如果您未能正确使用EDT。 Everything will seem to work fine, but every now and then you can get very strange behavior (because two threads will be doing things instead of one). 一切似乎都可以正常工作,但偶尔你会得到非常奇怪的行为(因为两个线程将做的事情而不是一个)。

So in summary you have to use invokeLater() , or in some exceptions invokeNow() in the following cases: 所以总结一下,你必须使用invokeLater() ,或者在下列情况下使用invokeNow()

  1. Constructing Swing components from the main thread. 从主线程构造Swing组件。
  2. Calling swing components from your personally created threads. 从您个人创建的线程中调用swing组件。
  3. Calling swing components from events on threads created by frameworks. 从框架创建的线程上的事件中调用swing组件。

This question contains some tools that can help you automatically detect errors (not all though). 这个问题包含一些可以帮助您自动检测错误的工具(尽管不是全部)。

where my Swing applications running on the EDT by default or were they running on a diffrent thread and i was just lucky not to have any issues with them? 默认情况下,我的Swing应用程序在EDT上运行,或者它们是在不同的线程上运行的,我很幸运,没有任何问题吗?

They were mostly being ran on the EDT. 他们大多是在美国东部时间跑。 All the painting and updating that Swing does by itself is on the EDT. Swing所做的所有绘画和更新都在EDT上。 Anything you do specifically in your code base that you know wasn't on the EDT, is the code that was not on the EDT. 你在代码库中专门做的事情,你知道的不是在EDT上,是EDT上没有的代码。 So these would be actions like querying the text of a JLabel, or setting the text of a JLabel, or initializing the JLabel itself. 所以这些操作就像查询JLabel的文本,设置JLabel的文本或初始化JLabel本身一样。

The various listener methods that are executed by Swing which you have implemented in your code base are however executed on the EDT (as long as Swing called it, not yourself). 然而,您在代码库中实现的Swing执行的各种侦听器方法都在EDT上执行(只要Swing调用它,而不是您自己)。 So in these methods you can query/modify Swing components, but remember to properly transfer in and out any data you give to a Swing component or queried from a Swing component in a thread-safe manner. 因此,在这些方法中,您可以查询/修改Swing组件,但请记住正确地传入和传出您提供给Swing组件的任何数据,或者以线程安全的方式从Swing组件查询。

Like for example if I create a JButton and add it to a JPanel or JFrame, are these operations running on the EDT by default or no? 例如,如果我创建一个JButton并将其添加到JPanel或JFrame,默认情况下这些操作是否在EDT上运行?

The initialization of the objects happens on whatever thread you created them on, and so are the rest of the modifications of the Swing objects (like adding one component to another). 对象的初始化发生在您创建它们的任何线程上,Swing对象的其余修改也是如此(例如将一个组件添加到另一个组件)。 I do not know of any Swing components whose public method implementations are wrapped in their own invokeNow() or invokeLater() call, so it's best to assume all portions of the actions happened on whatever thread you called the original methods on. 我不知道任何Swing组件的公共方法实现都包含在它们自己的invokeNow()或invokeLater()调用中,因此最好假设所有操作部分都发生在您调用原始方法的任何线程上。

do I have to explicitly send all my Swing components and methods to run on the EDT by invokingSwingUtilities.invokeLater() 我是否必须通过调用SWUUNITY.invokeLater()显式发送所有我的Swing组件和方法在EDT上运行

Yes, or invokeNow() 是的,或者是invokeNow()

Components will be accessed from within the thread context they are called, wch leads to a problem... 组件将从它们被调用的线程上下文中访问,wch会导致问题...

All Swing components (or enough not to matter) MIST be accessed within the context of the Event Dispatching Thread once they have been added to a displayable container (attached to a native peer). 一旦将事件调度线程的上下文添加到可显示的容器(连接到本地对等体),就可以在事件调度线程的上下文中访问所有Swing组件(或者根本不重要)。

This makes Swing components NOT thread safe and you are responsible for ensuring that they are modified/accessed from the EDT correctly, the framework will NOT do it for you 这使得Swing组件不是线程安全的,你有责任确保它们被正确地从EDT修改/访问,框架不会为你做

Take a look at Concurrency in Swing for more details 有关更多详细信息,请参阅Swing中的Concurrency

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM