如何在Java中强制关闭窗口?

如何在Java中强制关闭窗口?,java,swing,event-dispatch-thread,Java,Swing,Event Dispatch Thread,即使函数当前正在运行,我也希望强制关闭Java窗口——有没有办法做到这一点?我有一些函数在某些情况下需要很长时间(例如从CD或其他非本地位置运行),我希望能够强制停止这些函数并完全退出程序。这可能吗?我该怎么做呢 我的退出代码如下: this.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent wi

即使函数当前正在运行,我也希望强制关闭Java窗口——有没有办法做到这一点?我有一些函数在某些情况下需要很长时间(例如从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;
    }
}

快速编辑以澄清:当我的程序正在执行一个长时间运行的函数并且我试图关闭窗口时,窗口侦听器甚至不注册单击

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

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

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

要解决这个问题,您应该考虑长期运行的操作正在做什么。在任何情况下,都应将其移动到后台线程:

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

  • 否则如果在任何时候终止长时间运行的操作时发生错误,则应将该操作置于非守护进程线程中。在这种情况下,使用
    System.exit
    关闭应用程序也是一个坏主意,因为这也会杀死非守护进程线程。您需要实现一种机制,该机制可以优雅地终止后台线程,或者等待后台线程完成。这有时可能很困难,但却是必要的。这种长时间运行的操作的一个例子是写入文件:如果您只是终止此操作,那么文件将被损坏

另见

如果要对长时间运行的操作使用
ExecutorService
,则可能会对以下方法感兴趣:

启动有序关机,执行以前提交的任务,但不接受新任务


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

要解决这个问题,您应该考虑长期运行的操作正在做什么。在任何情况下,都应将其移动到后台线程:

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

  • 否则如果在任何时候终止长时间运行的操作时发生错误,则应将该操作置于非守护进程线程中。在这种情况下,使用
    System.exit
    关闭应用程序也是一个坏主意,因为这也会杀死非守护进程线程。您需要实现一种机制,该机制可以优雅地终止后台线程,或者等待后台线程完成。这有时可能很困难,但却是必要的。这种长时间运行的操作的一个例子是写入文件:如果您只是终止此操作,那么文件将被损坏

另见

如果要对长时间运行的操作使用
ExecutorService
,则可能会对以下方法感兴趣:

启动有序关机,执行以前提交的任务,但不接受新任务


停止JVM。这有什么不对?@bcsb1001窗口侦听器根本没有被击中-这是一个关于在第一时间实际访问该调用而不是在关闭事件触发后进行调用的问题。停止JVM。这有什么问题?@bcsb1001窗口侦听器根本没有被击中-这是一个关于在第一时间实际访问该调用而不是在关闭事件触发后进行调用的问题。我最终使用了一个SwingWorker,谢谢你的帮助!我对Java中的线程技术知之甚少,但你为我指明了正确的方向,所以谢谢你:)我最终使用了SwingWorker,谢谢你的帮助!我对Java中的线程技术知之甚少,但您为我指明了正确的方向,所以谢谢:)