MalcolmInTheCenter
MalcolmInTheCenter

Reputation: 1605

java Pause code and wait for user input

I wrote my program in two parts, I wrote the actual functionality first, and then the GUI to display it all. I need to wait/pause for a user to click a "Done" button from another class(DisplayImages) before continuing executing code. My DisplayImages class takes a list of MyImage. The images are then displayed in a jpanel and the user selects a couple of images and then clicks a 'Done' button. How can I wait for a response or something like that?

public class One{

    ArrayList<MyImage> images = new ArrayList<MyImage>();

    public One(){
        DisplayImages displayOne = new DisplayImages(images);
        displayOne.run();
        //I need to pause/wait here until the user has pressed the done button
        //in the DisplayImages class

        images.clear();
        images = displayOne.getSelectedImages();

        //do stuff here with images arrylist
        }
}    

DisplayImages class

public class DisplayImages extends JFrame{
    private ArrayList<MyImage> images = new ArrayList<MyImage>();
    private ArrayList<MyImage> selectedImages = new ArrayList<MyImage>();

    public DisplayImages(ArrayList<MyImage> images){
        this.images = images;
    }

    public void run(){
        //code creates a jpanel and displays images along with a done button

        //user presses done button
        done.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                selectedImages = getSelectedImages();
                //here I would send a signal to continue running in class One
            }
        });
    }

    private ArrayList<MyImage> getSelectedImages(){
        //code returns list of all the images the user selected on JPanel
        return results;
    }
}

Upvotes: 1

Views: 2685

Answers (3)

c.s.
c.s.

Reputation: 4826

If for some reason you need to open and process the dialog in the same method then using the dialog approach suggested with JOptionPane seems fine. However this seems bad design (opening a frame and waiting for input in a constructor?). I would prefer an approach similar to the one below (please read my inline comments):

public class One {

    ArrayList<MyImage> images = new ArrayList<MyImage>();

    public One() {
        // perform only initialization here
    }

    // call this method to create the dialog that allows the user to select images
    public void showDialog() {
        DisplayImages displayOne = new DisplayImages(images);

        // pass a reference to this object so DisplayImages can call it back
        displayOne.run(this);
    }

    // this will be called by the action listener of DisplayImages when Done is clicked
    public void processSelectedImages(List<MyImage> selectedImages) {
        images.clear();
        images = selectedImages;

        // do stuff here with images arrylist
    }
}


public class DisplayImages {
    ...
    public void run(final One callback){  // Note that now a reference to the caller is passed
         // creates jpanel and displays images along with a done button

         // user presses done button
         done.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e) {
                 setVisible(false);
                 selectedImages = getSelectedImages();

                 // here is how we can send a signal to notify the caller
                 callback.processSelectedImages(selectedImages); 
             }
         });
    }
    ...
}

As a side note please do not name your methods run() if you are not implementing the Runnable interface and/or using threads. This is very confusing

Upvotes: 2

gavlaaaaaaaa
gavlaaaaaaaa

Reputation: 652

You will have to use threading.

http://docs.oracle.com/javase/tutorial/essential/concurrency/

Then you can set up each instance on a separate thread, and either use the built in Object.notify and Object.wait

Or have yourself a global flag variable, static, available to both classes, which you change to notify the other class that the done button was clicked.

Upvotes: -1

Stephan
Stephan

Reputation: 4443

That is quite easy, some people here are thinking to complicated. You will need no multithreading, you just need a modal dialog. JOptionPane provides easy access to them.

I modified your code:

public class One{

    ArrayList<MyImage> images = new ArrayList<MyImage>();

    public One(){
        DisplayImages displayOne = new DisplayImages(images);
        int n = JOptionPane.showConfirmDialog(null, displayOne);

        if (n == JOptionPane.OK_OPTION){
          //I need to pause/wait here until the user has pressed the done button
          //in the DisplayImages class

          images = displayOne.getSelectedImages();

          //do stuff here with images arrylist
          }
        }
}    

MyImage class

public class DisplayImages extends JPanel{
    private ArrayList<MyImage> images = new ArrayList<MyImage>();

    public DisplayImages(ArrayList<MyImage> images){
        this.images = images;

        //code creates a jpanel and displays images along with a done button
    }

    public ArrayList<MyImage> getSelectedImages(){
        //code returns list of all the images the user selected on JPanel
        return results;
    }
}

Upvotes: 1

Related Questions