Java 检测应用程序何时关闭
Java detect when application is closing
几年前我学了Java大约1年。现在我想回去,但我的技能有点生疏了。因此,我将 Eclipse 与 WindowBuilder 一起使用来制作一个简单的表单应用程序,以便重新开始。我想在退出应用程序时弹出 window,因为在未来的项目中,当应用程序通过我自己的退出按钮以外的其他方式退出时,我需要执行一些代码(例如通过红叉或 Alt+ F4).
到目前为止,这是我的代码:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Mainframe {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
JOptionPane.showConfirmDialog(null, "Do you", "Message",
JOptionPane.YES_NO_OPTION);
MessageBox.infoBox("YOUR INFORMATION HERE", "TITLE BAR MESSAGE");
}
});
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Mainframe window = new Mainframe();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Mainframe() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
frame.getContentPane().add(btnNewButton, BorderLayout.SOUTH);
}
}
我使用了 this 中 "when the Application is being exited" 的代码
例如,但无论我如何关闭它,都没有"Messagebox is appearing"。当我直接在 main void 之后使用 MessageBoxes 的代码时,MessageBoxes 出现了,所以我想我放错了 ShutdownHook。
如果有人能帮我解决这个问题,我将不胜感激。
关闭挂钩用于在应用程序关闭后(通过 System.exit
调用或来自 OS).它不适用于此类对话。
您需要向 JFrame
添加 WindowListener
,并对 windowClosing
and/or windowClosed
事件执行操作。在这个侦听器中,您可以显示一个对话框或任何您想要的内容。
如果您希望能够覆盖 window 的关闭,您可以在 this question.
上找到有关如何操作的详细信息
我参加这里的派对有点晚了,但我想我会加 2 美分。我认为最好使用允许关闭侦听器的静态 class。它不那么复杂,并且允许检查 JVM 当前是否正在关闭(例如:隐藏日志消息)。这是我使用的实现:
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
public enum ShutdownNotifier {
INSTANCE;
private static final Class<?> THIS_CLASS = new Object() {
}.getClass().getEnclosingClass();
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(THIS_CLASS);
private Set<AutoCloseable> _listeners;
private CompletableFuture<Void> _shutdownFuture;
public boolean isShuttingDown() {
return getShutdownFuture().isDone();
}
public boolean addListener(AutoCloseable listener) {
if (listener == null)
return false;
var listeners = this.getListeners();
boolean added;
synchronized (listeners) {
added = listeners.add(listener);
}
if (this.isShuttingDown()) {
this.notifyListeners();
return true;
}
return added;
}
public boolean removeListener(AutoCloseable listener) {
if (listener == null)
return false;
var listeners = getListeners(false);
if (listeners == null)
return false;
synchronized (listeners) {
return listeners.remove(listener);
}
}
private Set<AutoCloseable> getListeners() {
return getListeners(true);
}
private Set<AutoCloseable> getListeners(boolean create) {
if (_listeners == null && create)
synchronized (this) {
if (_listeners == null && create)
_listeners = new HashSet<>();
}
return _listeners;
}
private CompletableFuture<Void> getShutdownFuture() {
if (_shutdownFuture == null)
synchronized (this) {
if (_shutdownFuture == null) {
var future = new CompletableFuture<Void>();
future.whenComplete((v, t) -> {
notifyListeners();
});
try {
Runtime.getRuntime().addShutdownHook(new Thread(() -> future.complete(null)));
} catch (IllegalStateException e) {
future.complete(null);
}
_shutdownFuture = future;
}
}
return _shutdownFuture;
}
private void notifyListeners() {
var listeners = getListeners(false);
if (listeners == null)
return;
while (true) {
AutoCloseable listener;
synchronized (listeners) {
var iter = listeners.iterator();
if (!iter.hasNext())
break;
listener = iter.next();
iter.remove();
}
try {
listener.close();
} catch (Throwable t) {
logger.warn("shutdown listener invocation failed", t);
}
}
}
}
几年前我学了Java大约1年。现在我想回去,但我的技能有点生疏了。因此,我将 Eclipse 与 WindowBuilder 一起使用来制作一个简单的表单应用程序,以便重新开始。我想在退出应用程序时弹出 window,因为在未来的项目中,当应用程序通过我自己的退出按钮以外的其他方式退出时,我需要执行一些代码(例如通过红叉或 Alt+ F4).
到目前为止,这是我的代码:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Mainframe {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
JOptionPane.showConfirmDialog(null, "Do you", "Message",
JOptionPane.YES_NO_OPTION);
MessageBox.infoBox("YOUR INFORMATION HERE", "TITLE BAR MESSAGE");
}
});
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Mainframe window = new Mainframe();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Mainframe() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
frame.getContentPane().add(btnNewButton, BorderLayout.SOUTH);
}
}
我使用了 this 中 "when the Application is being exited" 的代码 例如,但无论我如何关闭它,都没有"Messagebox is appearing"。当我直接在 main void 之后使用 MessageBoxes 的代码时,MessageBoxes 出现了,所以我想我放错了 ShutdownHook。
如果有人能帮我解决这个问题,我将不胜感激。
关闭挂钩用于在应用程序关闭后(通过 System.exit
调用或来自 OS).它不适用于此类对话。
您需要向 JFrame
添加 WindowListener
,并对 windowClosing
and/or windowClosed
事件执行操作。在这个侦听器中,您可以显示一个对话框或任何您想要的内容。
如果您希望能够覆盖 window 的关闭,您可以在 this question.
上找到有关如何操作的详细信息我参加这里的派对有点晚了,但我想我会加 2 美分。我认为最好使用允许关闭侦听器的静态 class。它不那么复杂,并且允许检查 JVM 当前是否正在关闭(例如:隐藏日志消息)。这是我使用的实现:
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
public enum ShutdownNotifier {
INSTANCE;
private static final Class<?> THIS_CLASS = new Object() {
}.getClass().getEnclosingClass();
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(THIS_CLASS);
private Set<AutoCloseable> _listeners;
private CompletableFuture<Void> _shutdownFuture;
public boolean isShuttingDown() {
return getShutdownFuture().isDone();
}
public boolean addListener(AutoCloseable listener) {
if (listener == null)
return false;
var listeners = this.getListeners();
boolean added;
synchronized (listeners) {
added = listeners.add(listener);
}
if (this.isShuttingDown()) {
this.notifyListeners();
return true;
}
return added;
}
public boolean removeListener(AutoCloseable listener) {
if (listener == null)
return false;
var listeners = getListeners(false);
if (listeners == null)
return false;
synchronized (listeners) {
return listeners.remove(listener);
}
}
private Set<AutoCloseable> getListeners() {
return getListeners(true);
}
private Set<AutoCloseable> getListeners(boolean create) {
if (_listeners == null && create)
synchronized (this) {
if (_listeners == null && create)
_listeners = new HashSet<>();
}
return _listeners;
}
private CompletableFuture<Void> getShutdownFuture() {
if (_shutdownFuture == null)
synchronized (this) {
if (_shutdownFuture == null) {
var future = new CompletableFuture<Void>();
future.whenComplete((v, t) -> {
notifyListeners();
});
try {
Runtime.getRuntime().addShutdownHook(new Thread(() -> future.complete(null)));
} catch (IllegalStateException e) {
future.complete(null);
}
_shutdownFuture = future;
}
}
return _shutdownFuture;
}
private void notifyListeners() {
var listeners = getListeners(false);
if (listeners == null)
return;
while (true) {
AutoCloseable listener;
synchronized (listeners) {
var iter = listeners.iterator();
if (!iter.hasNext())
break;
listener = iter.next();
iter.remove();
}
try {
listener.close();
} catch (Throwable t) {
logger.warn("shutdown listener invocation failed", t);
}
}
}
}