Tutorial zawsze warto sobie przypomnieć: http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html#eg
A tu najmniejszy kawałek kodu działający w ten sposób z "czystym" (bez wymuszania System.exit
) zamknięciem okna.
class MyJFrame extends WindowAdapter implements Runnable
{
public static void main(String[] args) { SwingUtilities.invokeLater(new MyJFrame()); }
public MyJFrame() { frame = new JFrame(); text = new JTextArea(); }
@Override public void run()
{ //wygląd systemowy
try { UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName()); }
catch(UnsupportedLookAndFeelException | ClassNotFoundException |
InstantiationException | IllegalAccessException e) {}
//kolory systemowe
text.setBackground(SystemColor.desktop);
text.setForeground(SystemColor.windowText);
//wyświetlanie tekstu logów w oknie
final Font f = text.getFont();
text.setFont(f.deriveFont(f.getSize2D() * 2));
//stan początkowy
text.setEditable(false); //bez pisania po JTextArea przez usera
text.setText("Otwarto okno\n");
//właściwości okna
frame.setTitle("Okno do zamknięcia");
frame.setPreferredSize(new Dimension(712, 400));
frame.getContentPane().add(new JScrollPane(text));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH); //zmaksymalizowane
//bez automatycznego windowClosed|JVM exit
//czyli zamknięcie okna dopiero po wywołaniu dispose()
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(this);
frame.setVisible(true);
text.append("Oczekiwanie na zamknięcie...\n");
}
//dwie metody implementujące WindowListener przez dziedziczony WindowAdapter
@Override public void windowClosing(WindowEvent e)
{
text.append("Próba zamykania okna...\n");
final int result = JOptionPane.showConfirmDialog(frame, "Zamykać?");
if(result == 0) //Yes (dobre powody zamknięcia okna)
{
frame.setVisible(false); //dispose() też to robi gdy zapomniano
frame.dispose(); //w konsekwencji odpalenie windowClosed via GUI
}
else if(result == 1) //No
text.append("Odmówiono zamknięcia...\n");
else //Cancel
text.append("Anulowano operację...\n");
}
@Override public void windowClosed(WindowEvent e)
{
System.out.println("Zamknięto okno..."); //nie ma już kontrolki dla text
frame.removeWindowListener(this); //usunięcie ostatniego callbacka
//teraz Swing (de facto JVM) spróbuje czystego usunięcia
//schowanej kontrolki okna po wykonanym dispose obiektu
}
//...
private JFrame frame;
private JTextArea text;
}
Kod został ścięty z większego przykładu, ale po drobnych uzupełnieniach (np. importy) powinien odpalić.