user592704 user592704 - 4 months ago 20
Java Question

how to block main thread as JOptionPane does?

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

Answer

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