设置setDefaultCloseOperation以显示JFrame窗口

7

我正在制作一个文字处理应用程序,以练习Java语言,并希望在用户尝试关闭应用程序时,会弹出一个JFrame询问是否保存更改。

我曾考虑使用setDefaultCloseOperation()方法,但是目前进展不大。如果可能的话,我也希望在用户单击窗口右上角的“X”时出现这个JFrame。

3个回答

15

您可以将JFrame的DefaultCloseOperation设置为DO_NOTHING,然后设置一个WindowsListener来捕获关闭事件并执行您想要的操作。我会在几分钟内发布一个示例。

编辑:这是示例:

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);
    }

  1. 如果不这样做,编译时会出错:ITYM frame.addWindowListener(new WindowAdapter() {
  2. 由于EDT仍在运行,JRE不会结束。这是少见的需要调用System.exit(0)的情况之一。
- Andrew Thompson
@AndrewThompson,您认为除了System.exit(0)之外,关闭应用程序的最安全方法是什么? - Andrei0427
好的,你可以首先查看正在运行的线程,并检查它是否只有EDT仍在运行。如果是这样,使用System.exit(0)结束JVM将是非常安全的。但是,在这里有一个更好的解决方案,请参见我的答案。 - Andrew Thompson
@AndrewThompson 1) WindowListener正常工作,并且是addWindowListener中定义的参数类型。2) EDT在框架被处理后停止(并且JRE正确结束),但也许有一些情况它不会停止(从未遇到过)。 - phsym
1
有一些情况是不会发生的,例如我的Oracle提供的JRE。(从未遇到过这种情况。)好啊,来我这里吧!带上啤酒... - Andrew Thompson

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

public class QuickGuiTest {

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

                frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
                frame.setSize(600, 400);
                frame.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosing(WindowEvent e) {
                        int result = JOptionPane.showConfirmDialog(
                                frame, "Are you sure?");
                        if( result==JOptionPane.OK_OPTION){
                            // NOW we change it to dispose on close..
                            frame.setDefaultCloseOperation(
                                    JFrame.DISPOSE_ON_CLOSE);
                            frame.setVisible(false);
                            frame.dispose();
                        }
                    }
                });
                frame.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

3
  • 你需要在JFrame中添加一个WindowListener

  • 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();
            }
        });
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接