如何在 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.
我想强制关闭一个 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.