2010-06-12 14 views
17

如果您在Swing打开一个对话框,例如一个JFileChooser,它会有点像这样的伪代码:Swing对话框如何工作?

swing event thread { 
    create dialog 
    add listener to dialog close event { 
    returnValue = somethingFromDialog 
    } 
    show dialog 
    (wait until it is closed) 
    return returnValue 
}

我的问题是:怎么能这样可能工作呢?正如你所看到的,线程等待返回,直到关闭对话框。这意味着Swing事件线程被阻塞。但是,可以与AFAIK需要此线程运行的对话进行交互。

那么这是如何工作的?

回答

6

这是AWT的主题,而不是Swing的主题。

无论如何,AWT运行show内的调度回路。输入事件阻止窗口被阻止。重新绘制事件,解除阻塞的窗口和一般事件的事件将照常发送。

Thread.dumpStack(); 

到甚至在命令行处理的模态对话框,或更容易与jstack或在的命令窗口中使用ctrl-\/ctrl-break

您可以通过添加一行看到这应用。

Foxtrot图书馆滥用此功能以提供更多程序性(而不是事件驱动)模型。它也被WebStart/Java PlugIn用于从应用程序EDT调用时为JNLP服务和其他对话提供对话。

9

现有事件分派线程被阻塞,因此swing会创建另一个线程来抽取事件。这是对话期间的事件分派线程。

Swing创建一个单独的本地线程来抽取本机操作系统窗口消息。这与AWT事件线程是分开的。

在Windows上,你看到的这些线程

"AWT-Windows" - the native UI thread 
    "AWT-EventQueue-0" - the current AWT event dispatch thread 

编辑:downvote是正确的。这是不正确的,至少在所有情况下都不是这样。

模态对话框通常会自行处理AWT事件。如果你运行代码

SwingUtilities.invokeAndWait(new Runnable() 
{ 
    public void run() 
    { 
     JOptionPane.showInputDialog("hello"); 
    } 
}); 

然后中断,看看线程,你会看到只有一个EventQueue线程。 JOptionPane的show()方法自行泵事件。

Spin和Foxtrot这样的框架采用相同的方法 - 它们允许您在EDT上创建一个长时间运行的阻塞方法,但通过自己抽取事件来保持事件的流畅性。有可能让swing有多个调度线程(我确定这是旧版swing的情况),但现在多核是常见的并发问题,尤其是确保一个线程上的更改能够正确发布到其他线程,意味着使用多个EDT会在当前实现中产生错误。请参阅 Multiple Swing event-dispatch threads

+0

这就解释了一些事情。 Upvoted你的答案,但其他人downvoted两个: -/ – 2010-06-12 13:47:20

+0

我低估了它,因为它是不正确的。 – 2010-06-12 13:51:14

+0

downvote是正确的 - 我已经更新了我的回复。 – mdma 2010-06-12 13:59:22