如何停止Swing EDT

时间:2011-01-28 21:47:24

标签: java swing event-dispatch-thread

典型的Swing应用程序在开始时启动EDT,当最后一个窗口关闭时,Application基本上使用隐式或显式的System.exit停止。

但是我的小应用程序实际上是一个对Swing一无所知的框架的插件。我的插件将在调用时显示一个对话框,以便从用户那里获得一些输入并在之后退出,但框架将/必须继续运行。所以我不能打电话给System.exit

但如果我不这样做,EDT将继续运行,一旦框架完成,EDT仍将运行并运行并运行......

所以我想在不杀死应用程序的情况下杀死EDT。我该怎么做?

2 个答案:

答案 0 :(得分:12)

来自Oracle / Sun的以下文档阐述了该问题:AWT Threading Issues

  

[...]

     

在1.4之前,辅助线程从未被终止。

     

从1.4开始,由于修复了4030718,行为发生了变化。使用当前实现,当以下三个条件成立时,AWT终止其所有辅助线程,允许应用程序干净地退出:

     
      
  • 没有可显示的AWT或Swing组件。
  •   
  • 原生事件队列中没有本机事件。
  •   
  • java EventQueues中没有AWT事件。
  •   
     

因此,希望在不调用System.exit的情况下干净地退出的独立AWT应用程序必须:

     
      
  • 确保应用程序完成后,所有AWT或Swing组件都不可显示。这可以通过在所有顶级Windows上调用Window.dispose来完成。请参见Frame.getFrames。 ......
  •   
  • 确保应用程序使用任何AWT或Swing组件注册的AWT事件侦听器的任何方法都无法运行到无限循环或无限期挂起。例如,由某些AWT事件触发的AWT侦听器方法可以将相同类型的新AWT事件发布到EventQueue。参数是AWT事件侦听器的方法通常在辅助线程上执行。
  •   
     

[...]

答案 1 :(得分:1)

可能存在一些隐藏的窗口(例如,使用JOptionPane.showMessageDialog(…)显示的对话框已经关闭),防止Swing退出。您可以使用

进行检查
Stream.of(Window.getWindows()).forEach(System.out::println);

如果你不再需要它们,你可以轻松摆脱它们:

Stream.of(Window.getWindows()).forEach(Window::dispose);

然后应该停止事件发送线程。