【问题标题】:JDialog refuses to closeJDialog 拒绝关闭
【发布时间】:2012-07-31 08:29:49
【问题描述】:

我正忙着制作一个基本的 Java 文字处理器作为个人项目,它包括一个弹出式 JDialog。但是,当用户单击“取消”按钮时,JDialog 拒绝关闭,关闭它的唯一方法是使用框架本身的关闭按钮。同样,当“确认”按钮被激活时,任务完成但 JDialog 保持打开状态。任何人都可以帮忙吗? 我的 JDialog 初始化代码:

    package cword;

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

    public class AlreadyExists extends JDialog
    {
        public static final long serialVersionUID = 1L;
        public AlreadyExists(Frame owner, String pathname, String filename, boolean includedExtension)
        {
            super(owner);
            initComponents(pathname, filename, includedExtension);
        }

        private void initComponents(final String pathname, String filename, final boolean includedExtension)
        {
            dialogPane = new JPanel();
            contentPanel = new JPanel();
            label1 = new JLabel();
            buttonBar = new JPanel();
            okButton = new JButton();
            cancelButton = new JButton();

            setTitle("Confirm Overwrite");
            Container contentPane = getContentPane();
            contentPane.setLayout(new BorderLayout());

            {

                dialogPane.setLayout(new BorderLayout());

                {
                    contentPanel.setLayout(null);

                    label1.setText("File " + filename + " already exists. Are you sure you want to overwrite?");
                    contentPanel.add(label1);
                    label1.setBounds(new Rectangle(new Point(0, 5), label1.getPreferredSize()));

                    {
                        Dimension preferredSize = new Dimension();
                        for(int i = 0; i < contentPanel.getComponentCount(); i++) {
                            Rectangle bounds = contentPanel.getComponent(i).getBounds();
                            preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
                            preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
                        }
                        Insets insets = contentPanel.getInsets();
                        preferredSize.width += insets.right;
                        preferredSize.height += insets.bottom;
                        contentPanel.setMinimumSize(preferredSize);
                        contentPanel.setPreferredSize(preferredSize);
                    }
                }
                dialogPane.add(contentPanel, BorderLayout.CENTER);

                {
                    buttonBar.setBorder(new EmptyBorder(12, 0, 0, 0));
                    buttonBar.setLayout(new GridBagLayout());
                    ((GridBagLayout)buttonBar.getLayout()).columnWidths = new int[] {0, 85, 80};
                    ((GridBagLayout)buttonBar.getLayout()).columnWeights = new double[] {1.0, 0.0, 0.0};

                    okButton.setText("Confirm");
                    buttonBar.add(okButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
                        GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                        new Insets(0, 0, 0, 5), 0, 0));

                    cancelButton.setText("Cancel");
                    buttonBar.add(cancelButton, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
                        GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                        new Insets(0, 0, 0, 0), 0, 0));
                }
                dialogPane.add(buttonBar, BorderLayout.SOUTH);
            }
            contentPane.add(dialogPane, BorderLayout.CENTER);
            pack();
            setLocationRelativeTo(getOwner());
            setDefaultCloseOperation(2);
            setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
            setVisible(true);
            okButton.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent ae)
                {
                    write(pathname, includedExtension);
                    close();
                }
            });
            cancelButton.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent ae)
                {
                    close();
                }
            });
        }

        private void write(String pathname, boolean includedExtension)
                {
            if(includedExtension)
            {
                try
                {
                    BufferedWriter writer;
                    writer = new BufferedWriter(new FileWriter(pathname));
                    writer.write(CWord.textArea1.getText());
                    writer.close();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
            else if(!includedExtension)
            {
                try
                {
                    BufferedWriter writer;
                    writer = new BufferedWriter(new FileWriter(pathname + ".txt"));
                    writer.write(CWord.textArea1.getText());
                    writer.close();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        }
        private void close()
        {
            dispose();
            dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
        }

        private JPanel dialogPane;
        private JPanel contentPanel;
        private JLabel label1;
        private JPanel buttonBar;
        private JButton okButton;
        private JButton cancelButton;
    }

在 CWord.class 中调用它的行之一:

    new AlreadyExists(this, file.getAbsolutePath(), file.getName(), true);

【问题讨论】:

    标签: java swing dispose jdialog


    【解决方案1】:

    好的,这很难,但我终于想通了!

    这是你的问题。您正在将ActionListeners 添加到您调用setVisible(true) 的按钮之后。由于这是一个模态对话框,setVisible(true) 是 EDT 上的阻塞调用。这意味着setVisible(true) 之后的代码直到对话框关闭后才会执行,因此ActionListeners 直到对话框关闭后才会添加到按钮中。

    当它是一个模态对话框时,在执行所有 GUI 初始化之后,您应该始终调用 setVisible()。因此,只需将 setVisible(true) 移到按钮上对 addActionListener 的调用之后,您就可以开始了。

    【讨论】:

      【解决方案2】:

      完全没有必要实现自己的对话框。

      改为围绕此计划您的代码:

      int choice = JOptionPane.showConfirmDialog(parentComponent, "Are you sure you want to overwrite?", "File Already Exists", JOptionPane.OK_CANCEL_OPTION);
      
       if(choice == JOptionPane.OK_OPTION){
           // okay
       } else {
           // cancelled
       }
      

      在此处阅读更多信息: How to Make Dialog - Java Tutorial # Custom Button Text

      【讨论】:

      • 但是,我如何检查它是否已被确认?而且,是否可以更改按钮上的文字?
      • 谢谢。但是,你能改变 JButton 的文本吗?
      • 你当然可以,看看教程中的例子。使用动词而不是 OK 和 Cancel 被认为是好的 UX。例如,将按钮的文本设置为覆盖和取消。
      • 你可以用这些对话框做很多事情,虽然不是一切(当然)。 ;)
      • @brimborium 哈哈老实说,我实际上已经创建了自己的对话框组件集,我一直使用它,但在这种情况下,我认为使用 Java 是合适的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-19
      • 2011-12-12
      • 2015-11-08
      相关资源
      最近更新 更多