Swing对话框如何工作?

Bar*_*lom 18 java swing multithreading jfilechooser jdialog

如果你在Swing中打开一个对话框,比如一个JFileChooser,它就像这个伪代码:

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

我的问题是:这怎么可能有效?如您所见,线程等待返回,直到对话框关闭.这意味着Swing事件线程被阻止.然而,人们可以与对话框进行交互,AFAIK需要该对话框才能运行.

那怎么办?

mdm*_*dma 9

现有的事件派发线程被阻止,因此swing创建另一个泵送事件的线程.这是对话期间的事件调度线程.

Swing创建了一个单独的本机线程,用于抽取本机OS窗口消息.这与AWT事件线程是分开的.

在Windows上,您可以看到这些线程

  "AWT-Windows"   - the native UI thread
  "AWT-EventQueue-0" - the current AWT event dispatch thread
Run Code Online (Sandbox Code Playgroud)

编辑:downvote是正确的.事实并非如此,至少在所有情况下都是如此.

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

SwingUtilities.invokeAndWait(new Runnable()
{
    public void run()
    {
        JOptionPane.showInputDialog("hello");
    }
});
Run Code Online (Sandbox Code Playgroud)

然后打破,看看线程,你只会看到一个EventQueue线程.JOptionPane的show()方法泵送事件本身.

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


Tom*_*ine 6

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

无论如何,AWT在内部运行调度循环show.被阻止的窗口的输入事件被阻止.像往常一样调度重新映射事件,事件到未阻止的窗口和一般事件.

您可以通过添加以下行来查看:

 Thread.dumpStack();
Run Code Online (Sandbox Code Playgroud)

进入模态对话框的均匀处理,或者更容易从命令行使用jstack或在应用程序的命令窗口中使用ctrl-\/ ctrl-break.

狐步库滥用这提供了更加程序(相对于事件驱动)模型.当从应用程序EDT调用时,WebStart/Java PlugIn也使用它来为JNLP服务和其他服务提供对话框.