如何在 Java 中强制关闭 window?

How to force-close a window in Java?

我想强制关闭一个 Java window,即使一个函数当前是 运行 - 有没有办法做到这一点?我有一些功能在某些情况下需要相当长的时间(例如,来自 CD 或其他非本地位置的 运行),我希望能够强制停止这些功能并完全退出程序。这可能吗?我该怎么做呢?

我的退出代码如下:

this.addWindowListener(new java.awt.event.WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent windowEvent) {
        if (closeApplication()) {
            System.exit(0);
        }
    }
});

和 closeApplication() 函数:

private boolean closeApplication() {
    final JFrame temp = this;
    int exitDialogResult = JOptionPane.showConfirmDialog(temp, 
            "Are you sure you want to exit?", "Really Closing?", 
            JOptionPane.YES_NO_OPTION,
            JOptionPane.QUESTION_MESSAGE);
    if (exitDialogResult == JOptionPane.YES_OPTION) {
            //code here to stop various processes               
            return true;
        }
    else {
        return false;
    }
}

快速编辑以澄清:当我的程序正在执行一个长 运行 函数并且我试图关闭 window 时,window 侦听器甚至没有注册点击.

您面临的问题很明显:您的应用程序在长时间的 运行 后台任务期间得到 "frozen",因为它在事件调度线程上执行。使用 SwingWorker。这样,当您的 运行 长任务在后台线程上运行时,您的 GUI 将保持响应。您可以使用 System.exit() 来终止,但最安全的方法是等到您的 运行 长任务完成。

您似乎正在事件分派线程中执行长运行 操作。这是 GUI 用来触发所有事件的线程。因此,如果您阻止该线程,您的 GUI 将被阻止。 JFrame 的关闭操作就是这些操作之一。这就是为什么在 GUI 线程中执行 long-运行 操作时不触发的原因。

要解决这个问题,您应该考虑 long-运行 操作在做什么。无论如何,您应该将其移至后台线程:

  • 它执行的操作是否可以随时取消,不会发生坏事?在这种情况下,您可以将操作放在守护进程中线。这告诉 JVM,这个线程可以随时终止。它不应该让 JVM 保持活动状态。一个示例是从 Web API.

  • 请求信息的操作
  • else 如果在任何时候终止 long-运行 操作时发生不好的事情,那么您应该将操作放在非-守护线程。在这种情况下,使用 System.exit 关闭您的应用程序也是一个坏主意,因为这也只会杀死非守护线程。您需要实现一种机制来优雅地终止后台线程,或等待它完成。这有时可能很困难,但这是必要的。此类长运行操作的一个示例是写入文件:如果您只是终止此操作,则文件将被损坏。

另见 What is Daemon thread in Java?

如果您想使用 ExecutorService 进行长时间 运行 操作,那么您可能会对方法 ExecutorService::shutdown:

感兴趣

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.