Подтверждение закрытия JFrame
5 апреля, 2010 2 комментария
Всем известно, что у JFrame окна имеется заголовок, на котором помимо всего прочего имеется кнопка закрытия окна. Возникают ситуации, при которых необходимо показать пользователю окно с подтверждением после нажатия на кнопку закрытия окна. Давайте посмотрим, как можно реализовать такой функционал. Первое, на что нужно обратить внимание это метод setDefaultCloseOperation класса JFrame. С помощью данного метода разработчик говорит JFrame, который он создает, что необходимо сделать при закрытии окна. Очень часто в этот метод передают константу JFrame.EXIT_ON_CLOSE. Если методу setDefaultCloseOperation передать эту константу, то при закрытии окна приложение будет прекращать работу. Сейчас нам понадобится передавать сюда константу JFrame.DO_NOTHING_ON_CLOSE. Если передать эту константу, то при закрытии окна ничего происходить не будет. Собственно это нам и надо, потому как закрытие окна и выход из приложения мы будем осуществлять из кода. Чтобы о том, что пользователь нажал кнопку закрытия окна необходимо повесить на JFrame слушателя WindowListener и реализовать у него метод windowClosing. Здесь мы покажем пользователю диалог подтверждения, проверим его реакцию (согласен закрыть окно или нет) и адекватно отреагируем.
Диалог показывать будем с помощью следующего кода.
Object[] options = { "Да", "Нет!" }; int n = JOptionPane.showOptionDialog(event.getWindow(), "Закрыть окно?", "Подтверждение", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
В переменную n будет возвращаться индекс варианта, который выбрал пользователь. То есть в данном случае n = 0, если пользователь выбрал «Да» и n = 1, если «Нет». Как только пользователь нажимает кнопку закрытия окна, срабатывает наш обработчик и у него вызывается метод windowClosing с параметром WindowEvent event. Этот параметр есть объект событие. Из него можно получить ссылку на окно Window, которое можем закрыть. Делаем это вот так.
event.getWindow().setVisible(false); System.exit(0);
С помощью второй строчки мы говорим системе, что необходимо завершить выполнение приложения. Если убрать её, то окно закроется, но приложение так и останется висеть в памяти. Вот и всё. А теперь тестовый пример.
import java.awt.Dimension; import java.awt.Font; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.UIManager; public class TestFrame extends JFrame { public static final Font FONT = new Font("Verdana", Font.PLAIN, 11); public static void createGUI() { JFrame frame = new JFrame("Test frame"); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.addWindowListener(new WindowListener() { public void windowActivated(WindowEvent event) { } public void windowClosed(WindowEvent event) { } public void windowClosing(WindowEvent event) { Object[] options = { "Да", "Нет!" }; int n = JOptionPane .showOptionDialog(event.getWindow(), "Закрыть окно?", "Подтверждение", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if (n == 0) { event.getWindow().setVisible(false); System.exit(0); } } public void windowDeactivated(WindowEvent event) { } public void windowDeiconified(WindowEvent event) { } public void windowIconified(WindowEvent event) { } public void windowOpened(WindowEvent event) { } }); frame.setPreferredSize(new Dimension(250, 250)); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { UIManager.put("Button.font", FONT); UIManager.put("Label.font", FONT); JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); createGUI(); } }); } }
Чтобы не писать лишнего, используйте адаптер:
frame.addWindowListener(new WindowAdapter(){ … });
в данном примере окно закрывается при любом варианте ответа (