0

I am busy making a basic Java word processor as a personal project, and it includes a popup JDialog. However, when the user clicks the 'Cancel' button, the JDialog refuses to close and the only way to close it is with the Close button on the frame itself. Similarly, when the 'Confirm' button is activated, the task is completed but the JDialog stays open. Can anyone help? My JDialog init code:

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

And one of the lines that call this in CWord.class:

    new AlreadyExists(this, file.getAbsolutePath(), file.getName(), true);
condorcraft110
  • 195
  • 1
  • 2
  • 8

2 Answers2

1

OK, this was a tough one, but I finally figured it out!

Here's your problem. You're adding the ActionListeners to the buttons after you call setVisible(true). Since this is a modal dialog, setVisible(true) is a blocking call on the EDT. This means that the code after setVisible(true) isn't executed until after the dialog is closed, so the ActionListeners aren't being added to the button until after the dialog is closed.

You should always have your call to setVisible() after all the GUI initialization is performed when it's a modal dialog. So just move setVisible(true) to after the calls to addActionListener on the buttons, and you'll be good to go.

Joe Attardi
  • 4,381
  • 3
  • 39
  • 41
0

There is absolutely no need to implement your own dialogs.

Plan your code around this instead:

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
 }

Read more here: How to Make Dialog - Java Tutorial # Custom Button Text

rtheunissen
  • 7,347
  • 5
  • 34
  • 65
  • But, how would I check if it had been confirmed? And, is it possible to change the text on the butttons? – condorcraft110 Jul 31 '12 at 08:38
  • Thanks. But, can you change the JButtons' text? – condorcraft110 Jul 31 '12 at 08:39
  • 1
    You sure can, look at the examples in the tutorial. It's considered good UX to use verbs instead of OK and Cancel. For example, set the buttons' text to Overwrite and Cancel instead. – rtheunissen Jul 31 '12 at 08:41
  • You can do a lot with those Dialogs, though not everything (of course). ;) – brimborium Jul 31 '12 at 08:43
  • @brimborium Haha to be honest, I actually have created my own dialog component set which I always use, but in this case I think it's appropriate to use the Java ones. – rtheunissen Jul 31 '12 at 08:55
  • @paranoid-android It's always a good idea to see if the standard dialogs can do the job. But I use my own versions too. ;) – brimborium Jul 31 '12 at 08:58
  • There are plenty of times you can benefit from implementing your own dialogs. And at any rate, it's a good learning exercise! – Joe Attardi Nov 28 '12 at 18:18