【问题标题】:How to avoid JFrame EXIT_ON_CLOSE operation to exit the entire application?如何避免 JFrame EXIT_ON_CLOSE 操作退出整个应用程序?
【发布时间】:2011-06-17 04:57:37
【问题描述】:

我有一个可以启动其他应用程序的应用程序,比如扩展坞。问题是,如果我正在启动的应用程序 (JFrame) 具有 EXIT_ON_CLOSE,它也会关闭我的主应用程序。

我无法控制我正在启动的应用程序。也就是说,我不能期望应用程序具有良好的行为并使用DISPOSE_ON_CLOSE

我可以做些什么来避免这种情况?我已经尝试过使用线程,但没有运气。我也尝试将主应用程序线程放在守护进程中,但也没有运气。

我尝试使用自定义 SecurityManager 覆盖 checkExit 方法。问题是现在即使是主应用程序也无法退出。此外,它不会“工作”,因为使用 EXIT_ON_CLOSE 作为默认关闭操作的应用程序将抛出异​​常并且不执行(因为 Swing 检查安全管理器的退出 -- System.checkExit()),无法启动:(。

【问题讨论】:

  • 您是在启动这个其他应用程序,如 frame.setVisible,还是通过 Runtime 或 Process Builder 创建一个新进程?
  • 我在特定的类加载器中通过反射启动。

标签: java multithreading swing jframe


【解决方案1】:

这有点小技巧,但您始终可以使用SecurityManager 来管理其他帧。

这个简单的例子防止框架退出:

import java.awt.*;
import javax.swing.*;

public class PreventExitExample {

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                PreventExitExample o = new PreventExitExample();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationByPlatform(true);
                f.setSize(new Dimension(400,200));
                f.setVisible(true);

                System.setSecurityManager(new PreventExitSecurityManager());
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

class PreventExitSecurityManager extends SecurityManager {

    @Override
    public void checkExit(int status) {
        throw new SecurityException("Cannot exit this frame!");
    }
}

【讨论】:

  • 是的,我认为例如开源项目 JDistro 就是这样做的。
  • 您好,使用自定义 SecurityManager 的问题是,现在连主应用程序都无法退出。此外,它不会“工作”,因为使用 EXIT_ON_CLOSE 作为默认关闭操作的应用程序将抛出异​​常并且不执行(因为 Swing 检查安全管理器的退出 -- System.checkExit())。
  • 如果您运行了该代码,您可能会看到主应用程序。 可以退出。
  • 好的,主应用可以退出了。但另一个应用程序将无法运行(即具有EXIT_ON_CLOSE 的应用程序。
  • @StefanDollase 删除了链接,包括一个例子。
【解决方案2】:

您可以使用获取所有帧的列表 Frame的静态方法 public static Frame[] getFrames()

迭代列表并检查列表成员是否为 instanceof JFrame 将默认关闭操作更改为 DISPOSE_ON_CLOSE

【讨论】:

    【解决方案3】:

    如果你只想关闭你看到的框架,它应该是DISPOSE_ON_CLOSE

    编辑:

    尝试拦截 EXIT_ON_CLOSE 事件。

    frame.getGlassPane() or frame.getRootPane()
    

    可能有用。

    另外,如果您有权执行其他应用程序的方法,您可以再次调用setDefaultCloseOperation,将其设置为DISPOSE_ON_CLOSE

    【讨论】:

    • 但是我无法控制要运行的应用程序。这就是问题所在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 2012-12-11
    • 2012-04-24
    • 2010-12-02
    • 2016-09-03
    • 1970-01-01
    相关资源
    最近更新 更多