2011-09-30 58 views
40

我似乎對大多數人都有相反的問題。我要看看下面的非常標準的代碼,如果用戶想要關閉該窗口之前做一些節省:Java - 如何防止WindowClosing實際關閉窗口

frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 
    frame.addWindowListener(new WindowAdapter() { 
    public void windowClosing(WindowEvent ev) { 
     boolean close = true; 
     // check some files, asking if the user wants to save 
     // YES and NO handle OK, but if the user hits Cancel on any file, 
     // I want to abort the close process  
     // So if any of them hit Cancel, I set "close" to false 
     if (close) { 
      frame.dispose(); 
      System.exit(0); 
     } 
     }    
}); 

無論我怎麼努力,當我走出來的windowClosing的窗口始終關閉。將WindowAdapter更改爲WindowListener沒有任何區別。奇怪的是,文檔中明確提到「如果程序在處理這個事件時沒有明確隱藏或者處理窗口,那麼窗口關閉操作將被取消」,但是這對我來說並不是那樣。有沒有其他的方式來處理框架上的x? TIA

+3

我敢打賭,如果您通過創建[sscce](http://sscce.org)儘可能簡化您的問題,那麼存在一個對您而言顯而易見的錯誤。如果它不明顯,那麼你可以發佈sscce,我們可以在它上面工作,最好能夠幫助你。 –

+2

根據提供的代碼,設置'close'變量的邏輯可能是錯誤的。由於它默認爲true,它會出現你不正確重置它。你是否在if語句之前打印了價值? – camickr

+1

我剛剛遇到另一種情況,如果使用Netbeans(8.0)可能導致這些症狀。Design View自動生成的代碼將添加其自己的默認關閉操作,該操作可以覆蓋人爲生成的代碼中指定的行爲。這可以在JDialog屬性框中進行編輯。 (留下評論給後代尋求類似問題的解決方案,儘管不是Paul的問題的答案)。 –

回答

59

我只是嘗試這樣做最小的測試案例:

import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 

import javax.swing.JFrame; 
import javax.swing.WindowConstants; 

public class test { 

    public static void main(String[] args) { 
     final JFrame frame = new JFrame("Test"); 
     frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 
     frame.addWindowListener(new WindowAdapter() { 
      public void windowClosing(WindowEvent ev) { 
       //frame.dispose(); 
      } 
     }); 
     frame.setVisible(true); 

    } 

} 

如果我保持通話處置評論,並點擊關閉按鈕,窗口不會退出。取消註釋並點擊關閉按鈕,窗口關閉。

我不得不猜測在你的邏輯中設置你的「關閉」變量有問題。嘗試雙重檢查。

+1

謝謝大家!我發現它並且確實是我的問題。知道這個簡單的案例的工作有很大的幫助! –

+1

請學習java命名約定並堅持使用它們 - 儘可能使用最短的測試用例+1 :-) – kleopatra

+1

設置默認的關閉操作對於我來說是關鍵的,如上面演示中所列出的,並在其他答案中提到。 – ajon

18

這是關鍵,methinks:frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);使我在製作的測試用例中有所不同。

+0

這是整個事情的關鍵。 EXIT_ON_CLOSE似乎覆蓋了其他答案中提到的所有內容。謝謝Ben! –

7

不知道從哪裏是你的問題,

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class ClosingFrame extends JFrame { 

    private JMenuBar MenuBar = new JMenuBar(); 
    private JFrame frame = new JFrame(); 
    private static final long serialVersionUID = 1L; 
    private JMenu File = new JMenu("File"); 
    private JMenuItem Exit = new JMenuItem("Exit"); 

    public ClosingFrame() { 
     File.add(Exit); 
     MenuBar.add(File); 
     Exit.addActionListener(new ExitListener()); 
     WindowListener exitListener = new WindowAdapter() { 

      @Override 
      public void windowClosing(WindowEvent e) { 
       int confirm = JOptionPane.showOptionDialog(frame, 
         "Are You Sure to Close this Application?", 
         "Exit Confirmation", JOptionPane.YES_NO_OPTION, 
         JOptionPane.QUESTION_MESSAGE, null, null, null); 
       if (confirm == JOptionPane.YES_OPTION) { 
        System.exit(1); 
       } 
      } 
     }; 
     frame.addWindowListener(exitListener); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.setJMenuBar(MenuBar); 
     frame.setPreferredSize(new Dimension(400, 300)); 
     frame.setLocation(100, 100); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private class ExitListener implements ActionListener { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      int confirm = JOptionPane.showOptionDialog(frame, 
        "Are You Sure to Close this Application?", 
        "Exit Confirmation", JOptionPane.YES_NO_OPTION, 
        JOptionPane.QUESTION_MESSAGE, null, null, null); 
      if (confirm == JOptionPane.YES_OPTION) { 
       System.exit(1); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ClosingFrame cf = new ClosingFrame(); 
      } 
     }); 
    } 
} 
+5

請勿使用幻數。 「確認== 0」是什麼意思?爲了更容易理解,你應該使用'confirm == JOptionPane.YES_OPTION'。 – camickr

+2

你是正確的編輯,謝謝 – mKorbel

4

對於這件事的處理做:
如果用戶選擇是,然後使用setDefaultCloseOperation(DISPOSE_ON_CLOSE);的是if else

大括號內如果取消然後使用setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

考慮實例:

int safe = JOptionPane.showConfirmDialog(null, "titleDetails!", "title!!", JOptionPane.YES_NO_CANCEL_OPTION); 

if(safe == JOptionPane.YES_OPTION){ 
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);//yes 

} else if (safe == JOptionPane.CANCEL_OPTION) { 
    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);//cancel 
} else { 
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);//no 
} 
+0

這個解決方案真的有效。 – karim

+0

謝謝@karim –

+0

謝謝如果我把這段代碼放在關閉事件中會阻止對話框關閉 – Cherif

0

不知道你的問題在哪裏,但這對我有用!

frame.addWindowListener(新WindowAdapter的(){

 public void windowClosing(WindowEvent evt){ 
         int res=JOptionPane.showConfirmDialog(null, 
           "Do you want to exit.?"); 
         if(res==JOptionPane.YES_OPTION){ 
           Cal.this.dispose(); 
         } 
     }        
    }); 
0

爲了解決我想這篇文章的第一個答案。 作爲單獨的應用程序它的工作原理相同的問題,但不是在我的情況。 也許不同的是在JFrame中(回答)和FrameView(我的情況)。

public class MyApp extends SingleFrameApplication { // application class of my project 
    ... 
    protected static MyView mainForm; // main form of application 
    ... 
} 
public class MyView extends FrameView { 
    ... 
    //Adding this listener solves the problem. 
    MyApp.getInstance().addExitListener(new ExitListener() { 

     @Override 
     public boolean canExit(EventObject event) { 
     boolean res = false; 
     int reply = JOptionPane.showConfirmDialog(null, 
       "Are You sure?", "", JOptionPane.YES_NO_OPTION); 
     if (reply == JOptionPane.YES_OPTION) { 
      res = true; 
     } 
     return res; 
     } 
     @Override 
     public void willExit(EventObject event) { 
     } 
    }); 
    ... 
} 
1

setDefaultCloseOperation()方法幫助的問題。https://chortle.ccsu.edu/java5/Notes/chap56/ch56_9.html

查看此連結

+0

雖然只有鏈接的答案是答案,但最好將解釋放在答案中,並使用鏈接作爲參考,因爲鏈接可能會中斷。 – C8H10N4O2