2013-07-23 3 views
1

Я написал свою программу в двух частях, сначала написал фактическую функциональность, а затем графический интерфейс, чтобы отобразить все. Мне нужно подождать/приостановить, чтобы пользователь нажал кнопку «Готово» из другого класса (DisplayImages), прежде чем продолжить выполнение кода. Мой класс DisplayImages содержит список MyImage. Изображения затем отображаются в jpanel, и пользователь выбирает пару изображений , а затем нажимает кнопку «Готово». Как я могу ждать ответа или что-то в этом роде?java Пауза код и ждать ввода пользователя

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 класса

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

ответ

2

Если по какой-то причине вам нужно открыть и обработать диалог в том же методе, то с помощью диалогового подхода, предложенного с JOptionPane кажется хорошо. Однако это кажется плохим дизайном (открытие кадра и ожидание ввода в конструкторе?). Я предпочел бы подход, аналогичный приведенному ниже (пожалуйста, прочитайте мои встроенные комментарии):

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

В качестве примечания, пожалуйста, не называйте ваши методы run() если вы не реализовав интерфейс Runnable и/или с использованием потоков. Это очень запутывает

+0

+1 Конечно, слушатель лучше, чем мое предложение, но я хотел, чтобы это было легко. – Stephan

+0

Это похоже на то, что я могу использовать. Возможно, мне придется использовать Reflection, поскольку public void run (final One callback) жестко закодирован, чтобы принимать только классы типа 1, но мне понадобятся другие вызовы, вызывающие вызов. – altoids

+0

@Miss_poker Вы можете сделать все классы как 'One' реализовать интерфейс (скажем,' Caller'), который будет иметь один метод 'public void processSelectedImages (List selectedImages)'. Затем 'DisplayImages.run()' изменится на 'public void run (конечный Caller caller)'. Если это еще недостаточно для вас, пожалуйста, отредактируйте свой вопрос, чтобы дать разъяснения относительно ваших ограничений. –

-1

Вы должны будете использовать многопоточность.

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

Затем вы можете настроить каждый экземпляр в отдельном потоке, а также использовать встроенный в Object.notify and Object.wait

Или себе глобальную переменную флаг, статический, доступный для обоих классов, которые вы изменить чтобы уведомить другой класс о нажатии кнопки done.

1

Это довольно легко, некоторые люди здесь думают о сложной ситуации. Вам не потребуется многопоточность, вам просто нужен модальный диалог. JOptionPane обеспечивает легкий доступ к ним.

Я изменил код:

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 класс

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; 
    } 
} 
Смежные вопросы