从代码中终止Swing应用程序的正确方法是什么,有哪些陷阱?
我试图在计时器启动后自动关闭我的应用程序.但是,仅仅呼吁dispose()
在JFrame
没有做的伎俩-窗口消失了,但应用程序并没有终止.但是,当使用关闭按钮关闭窗口时,应用程序会终止.我该怎么办?
您的JFrame默认关闭操作可以设置为" DISPOSE_ON_CLOSE
"而不是EXIT_ON_CLOSE
(为什么人们继续使用EXIT_ON_CLOSE超出我的范围).
如果您有任何未曝光的窗口或非守护程序线程,您的应用程序将不会终止.这应该被认为是一个错误(并使用System.exit解决它是一个非常糟糕的主意).
最常见的罪魁祸首是java.util.Timer和你创建的自定义线程.两者都应该设置为守护进程或必须被明确杀死.
如果要检查所有活动帧,可以使用Frame.getFrames()
.如果处理掉所有Windows /帧,则使用调试器检查仍在运行的任何非守护程序线程.
我想一个EXIT_ON_CLOSE
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
之前System.exit(0)
更好,因为您可以在实际离开应用程序之前编写一个Window Listener来进行一些清理操作.
那个窗口监听器允许你定义:
public void windowClosing(WindowEvent e) { displayMessage("WindowListener method called: windowClosing."); //A pause so user can see the message before //the window actually closes. ActionListener task = new ActionListener() { boolean alreadyDisposed = false; public void actionPerformed(ActionEvent e) { if (frame.isDisplayable()) { alreadyDisposed = true; frame.dispose(); } } }; Timer timer = new Timer(500, task); //fire every half second timer.setInitialDelay(2000); //first delay 2 seconds timer.setRepeats(false); timer.start(); } public void windowClosed(WindowEvent e) { //This will only be seen on standard output. displayMessage("WindowListener method called: windowClosed."); }
尝试:
System.exit(0);
原油,但有效.
可能是安全的方式是这样的:
private JButton btnExit; ... btnExit = new JButton("Quit"); btnExit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ Container frame = btnExit.getParent(); do frame = frame.getParent(); while (!(frame instanceof JFrame)); ((JFrame) frame).dispose(); } });
以下程序包括将在没有显式调用System.exit()的情况下终止缺少无关线程的程序的代码.为了将此示例应用于使用线程/侦听器/定时器/等的应用程序,只需要在actionPerformed()中手动启动WindowEvent之前插入清除代码请求(以及,如果适用,等待)它们的终止.
对于那些希望复制/粘贴能够完全按照所示运行的代码的人来说,最后会包含一个稍微丑陋但不相关的主要方法.
public class CloseExample extends JFrame implements ActionListener { private JButton turnOffButton; private void addStuff() { setDefaultCloseOperation(DISPOSE_ON_CLOSE); turnOffButton = new JButton("Exit"); turnOffButton.addActionListener(this); this.add(turnOffButton); } public void actionPerformed(ActionEvent quitEvent) { /* Iterate through and close all timers, threads, etc here */ this.processWindowEvent( new WindowEvent( this, WindowEvent.WINDOW_CLOSING)); } public CloseExample() { super("Close Me!"); addStuff(); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { CloseExample cTW = new CloseExample(); cTW.setSize(200, 100); cTW.setLocation(300,300); cTW.setVisible(true); } }); } }