2010-12-15_132914.png

Java 的 close event 有二種,一為 windowClosed,一為 windowClosing。在一般狀況下,按下右上角的 close 按鈕只會呼叫 windowClosing。因為 sdk source 找不到 Frame.java,所以不知道按了右上角 close 按鈕會做什麼動作。但是經由 JFrame.java 中的 processWindowEvent 函數得知,收到 WindowEvent.WINDOW_CLOSING 時,會做出下列動作。

  1. HIDE_ON_CLOSE: 隱藏視窗。
    只是隱藏視窗而已,並沒有結束程式。
  2. DISPOSE_ON_CLOSE: 釋放由此 Window、其子元件及其擁有的所有子元件所使用的所有本機螢幕資源。
    釋放完所有資源後,會執行 postWindowEvent(WindowEvent.WINDOW_CLOSED),產生 WINDOW_CLOSED 事件。不一定會終止程式,當 Java 虛擬機器中最後的可顯示視窗被釋放後,虛擬機器可能會終止。
  3. EXIT_ON_CLOSE: 終止當前正在運行的 Java 虛擬機器。
    直接終止程式。
  4. DO_NOTHING_ON_CLOSE: 啥事都不做。
protected void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if (e.getID() == WindowEvent.WINDOW_CLOSING) { switch(defaultCloseOperation) { case HIDE_ON_CLOSE: setVisible(false); break; case DISPOSE_ON_CLOSE: dispose(); break; case EXIT_ON_CLOSE: System.exit(0); break; case DO_NOTHING_ON_CLOSE: default: break; } } }

根據上述的行為,為了模擬 close 按鍵,並且達到有 windowClosing 及 windowClosed 雙事件的產生,在一般選單下的 Exit 功能就直接執行 dispatchEvent(new WindowEvent(JOptionPane.getRootFrame(), WindowEvent.WINDOW_CLOSING)); 即可,而且 JFrame 預設的 DefaultCloseOperation 要改成 DO_NOTHING_ON_CLOSE。最後在 windowClosing 加上 JOptionPane.showConfirmDialog 詢問是否結束程式,確定就執行 dispose() 即可。如果不放心程式沒有自動終止,可以在 windowClosed 加上 System.exit(0) 來強制終結程式。

package tw.idv.jyhshin.money; import java.awt.BorderLayout; public class test extends JFrame implements WindowListener { /** * */ private static final long serialVersionUID = 1L; private JPanel contentPane; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { test frame = new test(); JOptionPane.setRootFrame(frame); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public test() { addWindowListener(this); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); setTitle("test"); setBounds(100, 100, 450, 300); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); contentPane.setLayout(new BorderLayout(0, 0)); setContentPane(contentPane); JButton btnExit = new JButton("Exit"); btnExit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { dispatchEvent(new WindowEvent(JOptionPane.getRootFrame(), WindowEvent.WINDOW_CLOSING)); } }); contentPane.add(btnExit, BorderLayout.CENTER); } public void windowActivated(WindowEvent arg0) { System.out.println("activated"); } public void windowClosed(WindowEvent arg0) { System.out.println("closed"); System.exit(0); } public void windowClosing(WindowEvent arg0) { System.out.println("closing"); int close = JOptionPane.showConfirmDialog( JOptionPane.getRootFrame(), "確定要結束程式嗎?", "警告", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (close == JOptionPane.YES_OPTION) { dispose(); } } public void windowDeactivated(WindowEvent arg0) { System.out.println("deactivated"); } public void windowDeiconified(WindowEvent arg0) { System.out.println("deiconified"); } public void windowIconified(WindowEvent arg0) { System.out.println("iconified"); } public void windowOpened(WindowEvent arg0) { System.out.println("opened"); } }

台南小新 發表在 痞客邦 PIXNET 留言(0) 人氣()