问题 如何停止Swing EDT


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

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

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

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


5576
2018-01-28 21:47


起源



答案:


Oracle / Sun的以下文档阐述了该问题: AWT线程问题

[...]

在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侦听器方法可以向EventQueue发布相同类型的新AWT事件。参数是AWT事件侦听器的方法通常在辅助线程上执行。

[...]


11
2018-01-28 21:56



有一些问题,IIRC。你需要确保 dispose  所有 你的资源。 - Tom Hawtin - tackline


答案:


Oracle / Sun的以下文档阐述了该问题: AWT线程问题

[...]

在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侦听器方法可以向EventQueue发布相同类型的新AWT事件。参数是AWT事件侦听器的方法通常在辅助线程上执行。

[...]


11
2018-01-28 21:56



有一些问题,IIRC。你需要确保 dispose  所有 你的资源。 - Tom Hawtin - tackline


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

Stream.of(Window.getWindows()).forEach(System.out::println);

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

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

然后应该停止事件调度线程。


0
2017-11-14 19:11