1

我有多个自定义对话框,我想要一种简单的方法来指定关闭操作。首先,我使用匿名的内部 windowListener 类并以这种方式为每个对话框指定关闭方法。

我认为创建自己的类并实现 WindowListener 类并为所有对话框指定一个窗口关闭方法会更有效。

所以我这样做了,效果很好。

    public class WindowWatcher implements WindowListener{

    @Override
    public void windowClosing(WindowEvent e) {
        System.out.println("Are you sure you wish to exit?");
         int Answer = JOptionPane.showConfirmDialog(frame, "Are you sure want to exit?", "Quit", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
            if (Answer == JOptionPane.YES_OPTION) {
                System.exit(0);
            }
      }

    }

注意:类中还有其他实现的方法..

无论如何,我遇到的问题是当我单击退出时,然后单击否,然后我尝试继续进行对话框并说单击确定.. 没有任何反应。

我知道这与调用 JOptionPane 的 UNINITIALIZED_VALUE 有关。

我需要查看此 UNINITIALIZED_VALUE 的调用 optionPane。我认为??

就像是:

        optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE);

上面的代码假设我可以访问 optionPane。但是,在我的“WindowWatcher”类中,我无权访问它。

任何想法我怎么能做到这一点?也许我可以将 e.GetSource() 转换为 JOptionPane ..

编辑。

   ((JOptionPane)e.getSource()).setValue(JOptionPane.UNINITIALIZED_VALUE);

以上没有奏效。“无法将 JDialog 转换为 JoptionPane”

非常感谢!

4

3 回答 3

3
  • 请您使用此代码示例作为您的 SSCCE,

  • 放多个JDialogs,

  • 添加窗口监听器

  • 修改 showOptionDialog() 中的代码

  • 为 JOptionPane 传递父级

  • 从 showOptionDialog(...........) 开始

  • 然后我会在这里删除这个帖子

.

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

public class ClosingFrame extends JFrame {

    private JMenuBar MenuBar = new JMenuBar();
    private static JFrame frame = new JFrame();
    private static JFrame frame1 = new JFrame("DefaultCloseOperation(JFrame.HIDE_ON_CLOSE)");
    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) {
                frame.setVisible(false);
                /*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);
                }*/
            }
        };
        JButton btn = new JButton("Show second JFrame");
        btn.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                frame1.setVisible(true);
            }
        });
        frame.add(btn, BorderLayout.SOUTH);
        frame.addWindowListener(exitListener);
        frame.setDefaultCloseOperation(JFrame.HIDE_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();
                JButton btn = new JButton("Show first JFrame");
                btn.addActionListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        frame.setVisible(true);
                    }
                });
                frame1.add(btn, BorderLayout.SOUTH);
                frame1.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
                frame1.setPreferredSize(new Dimension(400, 300));
                frame1.setLocation(100, 400);
                frame1.pack();
                frame1.setVisible(true);
            }
        });
    }
}

编辑

你有这个“ExitListener”,当用户单击退出菜单项时效果很好,但是当我单击红色 x 时,它只是将可见设置为 false。我看不出这对 Dialog 或 JOptionPanes 有什么帮助。你想让我添加什么 windowListener?老实说更困惑。

  1. 因为我已经要求发布SSCCE

  2. 参见setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE, EXIT_ON_CLOSE, ....);API 中的方法

    • 默认值为JFrame.HIDE_ON_CLOSE, 显示并用作课程
    • 这是在 API 中实现的单独和直接的方法,
    • JFrame.HIDE_ON_CLOSE==frame.setVisible(false);
    • Swing GUI 需要更改为setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);,因为隐藏JFrameJDialog不等于当前 JVM 已终止,直到 PC 重新启动或关闭,EXIT_ON_CLOSE以终止当前 JVMSystem.exit(int);
  3. WindowListener是在 API 中实现的另一种单独且直接的方法,如何管理它

    • 阻止所有设置DefaultCloseOperation
    • 只会执行里面的代码windowXxx( Xxx == methods in WindowListener)
    • 否则什么都不会发生
  4. 回到我在这里发布的代码

    • 禁用frame.setVisible(false);==//frame.setVisible(false);
    • and (下一个代码行)删除/*and */,然后按照 am points 中的说明工作
于 2013-05-18T09:15:56.783 回答
1

我参加聚会可能有点晚了,但供将来参考:

注意:这种方法有点非传统,比一般方法要长一些,但它确实有效,所以如果归根结底,这是一个可以接受的解决方案。

我喜欢做的是完全跳过 JOptionPane 并使用 JDialog,只需在类的构造函数中构造消息和按钮,然后准备好 ActionListener 来捕获所有按钮,以防万一,将 WindowsListener 附加到对话框中,这样你就可以捕捉到所有可能的结果。

假设您正在使用自己班级的框架:

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

public class WindowCloseDialog implements ActionListener, WindowListener {

    private JDialog closeDialog;
    private JButton yesButton, noButton;

    WindowCloseDialog() {
        JFrame myFrame = new JFrame("Window Close Dialog Application");
        myFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        myFrame.addWindowListener(this);//catch the window being closed
        ...
        closeDialog = new JDialog("Quit");
        closeDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        closeDialog.addWindowListener(this);//catch the dialog being closed
        JLabel closeLabel = new JLabel("Would you like to exit?");
        yesButton = new JButton("Yes");
        yesButton.addActionListener(this);//catch an answer of yes
        noButton = new JButton("No");
        noButton.addActionListener(this);//catch an answer of no
        //add your components to your closeDialog in whatever manner you fancy
        ...
    }
    ...
    @Override
    public void windowClosing(WindowEvent w) {
        if (w.getWindow().equals(myFrame)) {
            closeDialog.setVisible(true);
        } else if (w.getWindow().equals(closeDialog)) {
            closeDialog.setVisible(false);//no exit on dialog close
        }
    }
    ...
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource().equals(yesButton)) {
            closeDialog.setVisible(false);
            myFrame.setVisible(false);
            System.exit(0);
        } else if (e.getSource().equals(noButton)) {
            closeDialog.setVisible(false);
        }
    }
    ...
}

如果你没有使用自己的类的框架,那么同样的规则仍然适用,因为如果是这种情况,另一个类说frame.addWindowListener(org.example.WindowWatcher);你会完全按照我的代码所要求的那样做,只需省略你自己构建的部分框架。

于 2013-07-15T08:20:49.120 回答
0

我认为创建自己的类并实现 WindowListener 类并为所有对话框指定一个窗口关闭方法会更有效。

好主意。我为此创建了自己的课程。请参阅关闭我的版本的应用程序。

您发布的代码对我来说看起来很合理。您是否在 if 语句中添加了 println() 语句,以查看是否调用了 System.exit() 方法。

我的解决方案略有不同。它default close operation为您管理框架。此值用于确定单击关闭图标时会发生什么。默认情况下,它必须设置为do nothing,以防用户取消关闭。如果用户接受关闭,那么您需要将其设置为您想要的属性。

于 2013-05-18T15:43:15.430 回答