setDefaultCloseOperation, чтобы вместо этого отображать JFrame

Я делаю приложение текстового процессора, чтобы практиковать Java, и мне бы хотелось, чтобы, когда пользователь пытается закрыть приложение, появится JFrame с просьбой сохранить изменения.

Я думал о setDefaultCloseOperation(), но пока мне не повезло. Я также хотел бы, чтобы он появлялся, когда пользователь нажимает «X» в правом верхнем углу окна, если это возможно.


person Andrei0427    schedule 31.08.2012    source источник


Ответы (2)


Вы можете установить для JFrame DefaultCloseOperation что-то вроде DO_NOTHING, а затем настроить WindowsListener для захвата события закрытия и выполнения того, что вы хотите. Я опубликую пример через несколько минут.

EDIT: Вот пример:

public static void main(String[] args) {
        final JFrame frame = new JFrame("Test Frame");

        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        frame.setSize(800, 600);

        frame.addWindowListener(new WindowAdapter() {
            //I skipped unused callbacks for readability

            @Override
            public void windowClosing(WindowEvent e) {
                if(JOptionPane.showConfirmDialog(frame, "Are you sure ?") == JOptionPane.OK_OPTION){
                    frame.setVisible(false);
                    frame.dispose();
                }
            }
        });

        frame.setVisible(true);
    }
person phsym    schedule 31.08.2012
comment
1) ITYM frame.addWindowListener(new WindowAdapter() { (иначе ошибка компиляции). 2) JRE не завершится, так как EDT все еще работает. Вот один из редких случаев, когда может потребоваться вызов System.exit(0). - person Andrew Thompson; 31.08.2012
comment
@AndrewThompson, какой самый безопасный способ закрыть приложение вместо System.exit(0); ? - person Andrei0427; 31.08.2012
comment
Что ж, вы можете сначала посмотреть на запущенные потоки и убедиться, что работает только EDT. Если это так, было бы совершенно безопасно завершить JVM с помощью System.exit(0). Но здесь есть лучшее решение, см. мой ответ. - person Andrew Thompson; 31.08.2012
comment
@AndrewThompson 1) WindowListener работает нормально, и это тип аргумента, определенный в addWindowListener. 2) EDT останавливается после того, как кадр был удален (и JRE правильно завершается), но, возможно, в некоторых случаях он не будет (никогда не встретится). - person phsym; 31.08.2012
comment
есть некоторые случаи, когда это не будет E.G. мой Oracle предоставил JRE. (никогда не встречал такого). Ну, иди ко мне домой! Принести пиво.. - person Andrew Thompson; 31.08.2012

  • Вы должны добавить WindowListener к JFrame.

  • Внутри метода windowClosing вы можете указать необходимый код.

Например:

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.OK_OPTION) {
                    System.exit(0);
                }
            }
        };
        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.OK_OPTION) {
                System.exit(0);
            }
        }
    }

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

            @Override
            public void run() {
                ClosingFrame cf = new ClosingFrame();
            }
        });
    }
}
person mKorbel    schedule 31.08.2012