你如何使用Event Dispatch Thread?

我了解了swing如何不是线程安全的。 深入研究,我发现对swing组件的每次修改都必须在Event Dispatch Thread上完成,以防止与multithreading相关的各种问题。 然而,信息似乎完全停在那里。 似乎没有一个很好的教程可以解释如何在互联网上随处访问。

将与其他问题相关的代码中的信息拼凑在一起,似乎我必须在我的程序中的每一个swing修改中放置一个不整齐的代码块(就像我自己的代码中的这个例子):

try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { setTitle("Frame title"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); setSize(800, 480); setLocationRelativeTo(null); setIconImage(Toolkit.getDefaultToolkit().createImage(ClassLoader.getSystemResource("Frame icon.png"))); } }); } catch (Exception e) { e.printStackTrace(); } 

基本上,这是对的吗? 我是否必须在代码中对Swing组件的每次修改周围放置该代码(或与invokeLater等效的代码)?

另外,为什么Swing不会自动执行此操作?

诀窍是,当挥动召唤你时,它总是在EDT中,所以你不必担心它。

但是,如果您处于计时器或由其他外部事件触发的操作,您的主线程或您创建的任何其他线程然后是,则必须使用invokeLater或invokeAndWait。

换句话说,是swing会自动执行“it”。 需要使用invokeXx是如此罕见,如果在内部进行摆动会浪费太多时间。

许多java程序员从来没有想到这一点,它可能会导致绘制GUI时出现一些非常讨厌的难以发现的问题。 我确实希望当你不使用EDT调用它时,swing会抛出一个例外 – 如果专业GUI出现,那么Java会有更好的声誉,因为那里会有更少的废话。

请注意,从事件处理程序执行的任何代码都已在EDT中运行(首字母缩略词中的事件)

这意味着对于一般用途(虽然你没有混乱使用swingworkers和线程池等)你总是在EDT里面

并且您始终可以使用SwingUtilities.isEventDispatchThread()查询您是否在EDT中

另请注意,在您的代码中,对invokeAndWait的调用将失败并在您进入EDT时抛出错误

基本上,您不会从EDT外部绘制或更新GUI。 您从另一个线程使用SwingUtilitis.invokeLater()以确保在EDT上运行GUI绘图或更新代码。

并非所有UI代码都必须是invokeLater调用中runnable的一部分。 这只是因为你的程序的很大一部分仍然会在EDT上运行。 只有在不同的线程上时才需要将消息发送到EDT。