【问题标题】:How to stop the Swing EDT如何停止 Swing EDT
【发布时间】:2011-01-28 21:47:24
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: java swing event-dispatch-thread


    【解决方案1】:

    来自 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 事件侦听器的方法通常在辅助线程上执行。

    [...]

    【讨论】:

    • 有一些问题,IIRC。你需要确保dispose所有你的资源。
    【解决方案2】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      • 2017-05-18
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      • 2015-04-23
      相关资源
      最近更新 更多