2

does anyone know how do we have a JOptionPane dialog above another JOptionPane dialog?

Pacerier
  • 86,231
  • 106
  • 366
  • 634

3 Answers3

7

I would use JDialogs for this as I think that this gives you a bit more control over how code gets run and displayed. But it could be done with JOptionPanes as well. For instance if you displayed a JButton in the JOptionPane whose ActionListener caused the display of another JOptionPane.

For e.g.,

import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class NestedJOptions {
   public static void main(String[] args) {
      final JPanel panel = new JPanel();
      panel.add(new JButton(new AbstractAction("Push Me") {
         public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(panel, "hello world!");
         }
      }));

      JOptionPane.showMessageDialog(null, panel);
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
2

EDIT: @Hovercraft Full of Eels provide a better solution; more likely what the OP was looking for.

From JOptionPane javadocs:

All dialogs are modal. Each showXxxDialog method blocks the caller until the user's interaction is complete.

So, no, you won't be able to achieve the desired functionality with JOptionPane. But JOptionPane is a convenience class to create few commonly encountered JDialogs. Since the functionality you want is not directly supported by JOptionPanes, you should consider implementing it directly using JDialogs. For instance:

public class DialogTest {
    static final SimpleDateFormat SDF = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss");

    public static void main(String[] args) {

        final JFrame frame = new JFrame("Dialog test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createPanelToPopDialog(frame));
        frame.setSize(500, 200);
        frame.show();
    }

    static JPanel createPanelToPopDialog(final JFrame parent) {
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        JButton button = new JButton("Pop a Dialog");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JDialog dialog = new JDialog(parent, true);
                dialog.add(createPanelToPopDialog(parent));
                dialog.setSize(500, 200);
                dialog.show();
            }
        });
        panel.add(button, BorderLayout.SOUTH);
        panel.add(new JLabel("Created at " + SDF.format(new Date())));

        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        return panel;
    }
}
Binil Thomas
  • 13,699
  • 10
  • 57
  • 70
-1

have you tried it and ran into some problem or you're just asking? JOptionPane is modal, so it blocks the thread it was created in. You can spawn several threads that show several JOptionPanes:

for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    JOptionPane.showMessageDialog(null, "I'm thread " + Thread.currentThread().getId());
                }
            });
            t.start();
        }

But only one message dialog will be able to receive swing events. You'd have to close them in the order they appeared (which is random).

Denis Tulskiy
  • 19,012
  • 6
  • 50
  • 68
  • 1
    Multi-threading would be a bad idea since all Swing code needs to be called from the same thread, the EDT, but furthermore it's not necessary. – Hovercraft Full Of Eels May 21 '11 at 19:39
  • Down-voted because now you're giving sample code that breaks the Swing single-thread rule, not good. I recommend you delete this answer. – Hovercraft Full Of Eels May 21 '11 at 19:42
  • @Hovercraft Full Of Eels: I believe Swing takes some extra safety measures when creating new windows, so starting several threads that create dialogs is ok, since only one modal window will be receiving swing events. One has to be extra careful, but it can be done. – Denis Tulskiy May 21 '11 at 19:43
  • No it should be one thread and one only since even JOptionPanes should be created on the EDT. Please see my post to see how it can all be done on the EDT. – Hovercraft Full Of Eels May 21 '11 at 19:44
  • @Hovercraft Full Of Eels: too much following rules is also bad. I was looking through AWT code for creating new dialogs, I'm sure there was synchronization and checking whether we're on a EDT or not. So I assume that this code answering the question is legit and does not break swing's rules. One has to be careful, but not super-pedantic. – Denis Tulskiy May 21 '11 at 19:52
  • @tulskiy well output/invoke to EDT will be correct if you create own thread by java.swing.Action, otherwise I agreed with Hovercraft Full Of Eels – mKorbel May 21 '11 at 20:33
  • @tulskiy: you may call it super-pedantic, but I call it being correct and safe. I know for a fact that calling JOptionPanes can easily break a Swing application as I've seen it happen myself in several situations. – Hovercraft Full Of Eels May 22 '11 at 03:26
  • @Hovercraft Full Of Eels btw what do you mean that a swing app can be broken by joptionpane? – Pacerier May 24 '11 at 01:56
  • @Pacerier: no I meant that an app can be broken infrequently and unpredictably by calling a JOptionPane off of the EDT. – Hovercraft Full Of Eels May 24 '11 at 02:07
  • @Hovercraft Full Of Eels: just out of curiosity, how was it broken? did you get some exceptions? did you use custom components as arguments to joptionpane? – Denis Tulskiy May 24 '11 at 03:49
  • @tulskiy: I've had the app lock up on me. For more on this, please see this SO thread: [is-joptionpane-showmessagedialog-thread-safe](http://stackoverflow.com/questions/1595744/is-joptionpane-showmessagedialog-thread-safe) – Hovercraft Full Of Eels May 24 '11 at 03:54