14

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

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

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

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

4

2 回答 2

14

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

[...]

于 2011-01-28T21:56:40.270 回答
2

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

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

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

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

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

于 2017-11-14T19:11:26.607 回答