【问题标题】:WindowClosing method窗口关闭方法
【发布时间】:2013-05-18 09:03:19
【问题描述】:

我有多个自定义对话框,我想要一种简单的方法来指定关闭操作。首先,我使用匿名的内部 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.setValue(JOptionPane.UNINITIALIZED_VALUE);

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

有什么想法可以做到这一点吗?也许我可以将 e.GetSource() 转换为 JOptionPane..

编辑。

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

上述方法无效。 "JDialog 不能转换为 JoptionPane"

非常感谢!

【问题讨论】:

  • JOptionPane 也有 CANCEL,我错过了目标
  • 请您在 Q 正文中丢失编辑,查看是否重要

标签: java swing joptionpane jdialog windowlistener


【解决方案1】:
  • 请您将此代码示例用作您的 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 时,它只是设置为可见 错误的。我看不出这对 Dialog 或 JOptionPanes .. 你想让我添加什么 windowListener?更多的 说实话很困惑。

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

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

    • 默认值为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 将当前JVM 终止为System.exit(int);
  3. WindowListener是API中实现的另一种独立直接的方法,如何管理它

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

    • 禁用frame.setVisible(false); == //frame.setVisible(false);
    • 和(下一个代码行)删除 /**/,然后按照上午点中提到的方式工作

【讨论】:

  • 我只是在检查您的代码。我的对话框和选项窗格都是在方法中创建的。我应该让它们成为我班级的变量吗?似乎有道理,然后我可以在任何地方访问它们。
  • @ mKorbel,您有这个“ExitListener”,当用户单击退出菜单项时效果很好,但是当我单击红色 x 时,它只是将可见设置为 false。我看不出这对 Dialog 或 JOptionPanes 有什么帮助。你想让我添加什么 windowListener?说实话更困惑。
【解决方案2】:

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

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

我喜欢做的是完全跳过 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);,所以你会完全按照我的代码要求做,只需省略部分您可以在其中构建自己的框架。

【讨论】:

    【解决方案3】:

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

    好主意。我为此创建了自己的课程。我的版本见Closing An Application

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

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

    【讨论】:

    • +1 以获得详细描述,我仍然认为 System.exit(0) 和 EXIT_ON_CLOSE 之间没有差异,用于其余 Java(non_deamon)线程,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 2012-12-15
    相关资源
    最近更新 更多