WindowClosing方法

时间:2013-05-18 09:03:19

标签: java swing joptionpane jdialog windowlistener

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

我需要看到调用optionPane到此UNINITIALIZED_VALUE。我想??

类似的东西:

        optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE);

上面的代码假设我可以访问optionPane。但是在我的班级'WindowWatcher'课程中,我无法访问它。

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

编辑。

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

以上都行不通。 “JDialog不能被视为JoptionPane”

非常感谢!

3 个答案:

答案 0 :(得分:3)

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

  • 放置多个JDialogs,

  • 添加WindowListener

  • 修改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);
    • 需要更改为setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);的Swing GUI,因为hidded JFrameJDialog不等于当前JVM终止,并且直到PC重新启动或关闭,{{ 1}}将当前JVM终止为EXIT_ON_CLOSE
  3. System.exit(int);是API中实现的另一个独立且直接的方法,如何管理

    • 阻止WindowListener
    • 的所有设置
    • 将仅执行DefaultCloseOperation
    • 内的代码
    • 否则没有任何事情发生
  4. 回到我在此处发布的代码

    • 停用windowXxx( Xxx == methods in WindowListener) == frame.setVisible(false);
    • 和(下一个代码行)删除//frame.setVisible(false);/*,然后按照a.m.中提到的那样工作

答案 1 :(得分: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);所以你会完全按照我的代码所要求做的,只是遗漏构建自己框架的部分。

答案 2 :(得分:0)

  

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

好主意。我已经创建了自己的类来做这件事。有关我的版本,请参阅Closing An Application

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

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