Search code examples
javaswingjdialog

Stop execution of program until JDialog is exited


I am trying to open up a bunch of JDialogs one after another. The goal is that only after one JDialog is closed the next one is created. I have tried to use setModal(true) for the dialogs, but somehow that does not make it work.

Just for you to get an idea, the code is roughly that:

for(Object o : mylist) {
    JDialog j = new JDialog();
    j.setModal(true);
}

The problem with that is that it opens up all the dialogs at once, so that multiple dialogs are open. How can I get what I want?


Solution

  • The following works for me. The below code displays a window containing a button with the text GO. When you click on the button, a JDialog appears with the title 0 (i.e. the digit zero) and a button with the text Close. When you click on the Close button, the JDialog disappears and another JDialog appears with the title 1 (i.e. the digit one) and a Close button. When you click on Close the JDialog disappears and another JDialog, with the title 2 appears.

    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    
    public class GUI {
        private JFrame  frame;
    
        private void closeDialog(ActionEvent event) {
            ((JDialog) ((JComponent) event.getSource()).getTopLevelAncestor()).dispose();
        }
    
        private void createAndDisplayGui() {
            frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JButton button = new JButton("GO");
            button.addActionListener(this::showDialogs);
            frame.add(button);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        private void showDialogs(ActionEvent event) {
            for (int i = 0; i < 3; i++) {
                JDialog dlg = new JDialog(frame, true);
                dlg.setTitle(Integer.toString(i));
                JButton b = new JButton("Close");
                b.addActionListener(this::closeDialog);
                dlg.add(b);
                dlg.pack();
                dlg.setLocationRelativeTo(frame);
                dlg.setVisible(true);
            }
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(() -> new GUI().createAndDisplayGui());
        }
    }
    
    • Method showDialogs is called when the GO button is clicked.
    • Method showDialogs creates a modal JDialog.
    • Calling method setVisible in the following line of code:
    dlg.setVisible(true);
    

    Method setVisible only returns after the modal JDialog has been closed.

    • When the Close button (in the JDialog) is clicked, method closeDialog is called.
    • Method closeDialog disposes the JDialog. Essentially the JDialog no longer exists after it has been disposed.
    • Each loop iteration (in method showDialogs) is performed only after the JDialog it displays has been closed.