2

I am just wondering... How to block main thread as JOptionPane (its confirmation dialog) does to be able hold execution until it returns some value? I've never done it before so I am interested to find an optimal way...

to be more clear I am interested to express the conception as something like this but I am not sure how to make it wait until an event happens in popupmenu for example:

...
int a;
int x;
void showPopup()
{

 a=MyPopupMenu.aPopupMenu();
 if(a==0){System.out.println("YES");}
 if(a==1){System.out.println("NO"); return;}

  x++; 
}

Thanks

user592704
  • 3,674
  • 11
  • 70
  • 107
  • 2
    The main thread doesn't stop, it's just that when you call the method to show the dialog, that method doesn't return until the user has finished using it. The main thread continues to execute, it's just that it's stuck inside of some loop in the dialog class. This sort of behavior on a dialog is known as modality - if the dialog is modal, then the user can't interact with anything outside of the dialog until the dialog is closed. – Nate W. Mar 31 '12 at 00:53
  • OK, but what if I want to simulate the "modality"? Is there a way? – user592704 Mar 31 '12 at 02:53
  • Post the code you are having problem with. – Java42 Mar 31 '12 at 05:04
  • Actually, I have no code problem but some conceptional problem :) So the thing is I am wondering can I get the "modality" effect with JPopupMenu for example? – user592704 Mar 31 '12 at 06:37
  • why do you want to annoy your users ;-) – kleopatra Mar 31 '12 at 09:23
  • Oh, it's not the point :) I just want to prevent the next code to be executed until some event happens; – user592704 Apr 01 '12 at 01:20

2 Answers2

2

Instead of using the static JOptionPane methods you can use an instance of a JDialog directly, allowing you to customize its behavior, such as the modality.

Nate W.
  • 9,141
  • 6
  • 43
  • 65
  • I'd love to use JDialog or something usual in this direction but the thing is I am interested to get the "modality effect" for any Swing component for example :S I saw codes like a http://stackoverflow.com/a/1595795/592704 but it uses SwingWorker; I am not pretty sure will it work in the question case ? – user592704 Mar 31 '12 at 06:42
2

Use wait/notify. The main thread will do:

synchronized(object) {
    object.wait(timeOut);
}

and the handler (ie listener) for whatever GUI you are using (a popup in your example) will do:

synchronized(object) {
    object.notify();
}

Here is a stripped-down instructional example using wait/notify

public class ModalPopUp {
JPopupMenu    popUpMenu;
JMenuItem     menuItem;
static Object modalMonitor = new Object();
public void popIt(Component parent, int x, int y) {
  popUpMenu.show(parent, x, y);
}
public void stopIt() {
  popUpMenu.setVisible(false);
}
public ModalPopUp() {
popUpMenu = new JPopupMenu();
menuItem = new JMenuItem("Click me to Continue");
popUpMenu.add(menuItem);
menuItem.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    synchronized (modalMonitor) {
      modalMonitor.notify();
    }
  }
});
}
public static void main(String args[]) throws Exception {
ModalPopUp p = new ModalPopUp();
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setVisible(true);
p.popIt(null, 100, 100);
System.out.println("Waiting upto 42s for popup click");
synchronized (modalMonitor) {
  modalMonitor.wait(42000);
}
p.stopIt();
System.out.println("Popup was clicked or 42s passed");
}
}
STaefi
  • 4,297
  • 1
  • 25
  • 43
Java42
  • 7,628
  • 1
  • 32
  • 50
  • I tried this but if I put the wait part at the end of aPopupMenu() method body the popupmenu never shows :( Could you give more details please – user592704 Apr 01 '12 at 02:36