does anyone know how do we have a JOptionPane dialog above another JOptionPane dialog?
3 Answers
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);
}
}

- 283,665
- 25
- 256
- 373
-
did you just propose to... yes you did ;-) Interesting way to accomplish something which might be what the OP was looking for. – Howard May 21 '11 at 19:38
-
this is way cool, btw Why does it work? shldn't all dialogs be modal? – Pacerier May 23 '11 at 01:50
-
@Pacerier: The dialogs are JOptionPanes, so yes of course they are all modal. – Hovercraft Full Of Eels May 23 '11 at 01:53
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 JDialog
s. Since the functionality you want is not directly supported by JOptionPane
s, you should consider implementing it directly using JDialog
s. 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;
}
}

- 13,699
- 10
- 57
- 70
-
I beg to differ. Please see my example code. It can't be done from the caller block's code, but it could be done from Swing code held by the JOptionPane. – Hovercraft Full Of Eels May 21 '11 at 19:36
-
@Hovercraft - agreed. I had forgotten the `JOptionPane` option which let you pass in your own `Component` to render. – Binil Thomas May 21 '11 at 19:56
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).

- 19,012
- 6
- 50
- 68
-
1Multi-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