views:

892

answers:

3

I have a program with a GUI that needs to open a separate window and wait for the user to select and option, then continue. I figure I should be doing this with the wait() and notify() methods, but I'm still trying to figure out exactly how to use those. A complicating factor is that things seem to work differently when the second window is created in an actionPerformed() method, which it needs to be.

Here's how I think it should be done here, apparently it is not quite right...

This should create a window with a button, when the button is pressed, another window with a button should be created, and when that button is pressed, the program should print "End".

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class WtfExample {

 public static void main(String[] args) {
  JFrame jf = new JFrame();
  JButton butt = new JButton("Button");
  butt.addActionListener(new ActionListener() {

   public void actionPerformed(ActionEvent e) {
    WtfExample we = new WtfExample();
    we.display();
   }
  });

  jf.getContentPane().add(butt);
  jf.setSize(new Dimension(1000, 500));
  jf.setVisible(true);

  System.out.println("End");
 }

 public synchronized void display() {
  JFrame jf = new JFrame();

  JButton butt = new JButton("Button");
  butt.addActionListener(new ActionListener() {

   public void actionPerformed(ActionEvent e) {
    synchronized(WtfExample.this) {
     WtfExample.this.notifyAll();
    }
   }
  });

  jf.getContentPane().add(butt);
  jf.setSize(new Dimension(1000, 500));
  jf.setVisible(true);

  while(true) {
   try {
    this.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
    break;
   }
  }
 }
}

edit- I wasn't clear enough in one thing- the second window that's opened is blank, like its components were never added to it. That's the case whether it's a frame or dialog, but that only happens if the window is created from the actionPerformed method.

+4  A: 

No, you should just be using a JDialog.

Jonathan Feinberg
It doesn't make a difference, and I don't think that's the issue here, the issue is with the wait and notify business.
Rob Lourens
wait and notify have nothing to do with this. This is not a synchronization and multithreading issue.
Bozho
So then how do i get it to let the program continue executing once the button has been clicked?
Rob Lourens
it is done automatically - that's the behaviour of _modal_ dialogs
Bozho
+2  A: 

You need a modal dialog window. Here's a tutorial on dialogs. It is easier to use JOptionPane for the simple cases.

A Dialog can be modal. When a modal Dialog is visible, it blocks user input to all other windows in the program.
Bozho
It doesn't seem to make a difference whether I use Dialog or Frame, but i probably should get it working with a Dialog since that seems to be more in line with what I'm using it for.
Rob Lourens
A: 

As the other two answers suggest you need a modal JDialog. You do not need to deal with any Thread classes. The JDialog window will deal with the giving you control back once the user input is handled. There are a few ways you can set the dialog box modal. Here are two examples.

new JDialog(Dialog owner, boolean modal)

or

new JDialog(Dialog owner, String title, boolean modal)

You could also do something like this:

JDialog dialog = new JDialog(owner);
dialog.setModal(true);

I think this is a pretty good article about modality in JAVA.

ralphL