2014-02-14 4 views
0

Вот мой пример кода:Как сделать нить ждать недо метод другого класса завершает

package javaapplication35; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import static javaapplication35.ProgressBarExample.customProgressBar; 
import javax.swing.JButton; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 
import javax.swing.SwingWorker; 

public class ProgressBarExample { 

final static JButton myButton =new JButton("Start"); 
final static JProgressBar customProgressBar = new JProgressBar(); 
private static final JPanel myPanel = new JPanel(); 

public static void main(String[] args) { 
    customProgressBar.setMaximum(32); 
    customProgressBar.setStringPainted(true); 
    myPanel.add(customProgressBar); 
    myPanel.add(myButton); 

    myButton.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) 
     { 

      Thread firstly =new Thread(new Runnable (
      ) { 
       @Override 
       public void run() { 
        Calculations a = new Calculations(); 
        a.doCaculations(); 
       } 
      });   

      Thread secondly =new Thread(new Runnable (
      ) { 
       @Override 
       public void run() { 
        JOptionPane.showMessageDialog(null,"just finished"); 
       } 
      }); 

      firstly.start(); 
      try { 
       firstly.join(); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(ProgressBarExample.class.getName()).log(Level.SEVERE, null, ex); 
      } 


      secondly.start(); 
     } 
    });   

    JOptionPane.showMessageDialog(null, myPanel, "Progress bar test", JOptionPane.PLAIN_MESSAGE); 

} 

} 

class Calculations { 
public void doCaculations() { 

    new SwingWorker<Void, Void>() { 
     @Override 
     protected Void doInBackground() throws Exception { 
      int value = 0; 
      while (value < customProgressBar.getMaximum()) { 
       Thread.sleep(250); 
       value ++; 
       customProgressBar.setValue(value); 
      } 
      return null; 
     } 
    }.execute(); 
} 

private void doOtherStaff(){ 
    //more methods, that don't need to run in seperate threads, exist 
} 

} 

Есть 2 темы. Нить firstly создает класс класса Calculations, а затем запускает метод doCaculations(). Тема сообщения: secondly.

Метод doCaculations() в моем «реальном» коде выполняет некоторые трудоемкие математические вычисления, и для имитации затраченного времени я добавил, что Thread.sleep(250);. Мне нужно сообщить пользователю о ходе вычислений, поэтому я использую панель прогресса, которая обновляется методом doCaculations().

Я пытаюсь сделать код работать таким образом, что поток secondly запускается после завершения резьбы firstly. Но я не могу заставить его работать. Случается, что всплывающее сообщение всплывает немедленно (и это означает, что он запускает поток, прежде чем я хочу его запустить).

Примечание: сообщение «только что закончилось» предназначено только для проверки кода. В моей «реальной» программе метод был бы на месте. Я делаю это примечание, потому что, если я просто хочу показать сообщение, я мог бы просто поместить его в конце метода doCaculations(), и все будет работать нормально.

Я знаю, что я должен делать неправильно с обработкой Thread, но я не могу его найти. Есть идеи?

PS: Мысль: На самом деле метод doCaculations() имеет свою собственную нить. Таким образом, он запускается «в SwingWorker внутри потока». Iguess firstly.join(); работает правильно. Но после того, как метод doCaculations() называется потоком fistrly, считается завершенным, и поэтому код продолжается с потоком secondly, не зная, что поток doCaculations() все еще что-то делает.

ответ

2

Попробуйте

a.doCaculations(); 
a.join(); 

редактировать:
Поскольку вы используете SwingWorker мой предыдущий ответ неверен, но, как комментарий, вы продлили тему, следующее должно работать для вас:

Thread a = new Calculations(); 
a.start(); 
a.join(); 

не забывайте, что вы должны переопределить run метод в классе Вычисления, как:

+0

Я «расширяет тему» ​​для класса вычислений, для того, чтобы использовать метод присоединиться на a, но ничего не меняется. Не могли бы вы дать более подробную информацию? – geo

+0

Я думаю, что это неправильно, поскольку он использует SwingWorker – aalku

+0

О, да, моя ошибка. Будет обновлен теперь мой пост для использования с Thread. – qiGuar

2

В Java вы можете использовать SwingWorker и в методе делается() вызвать ваш диалог

В Android вы можете использовать AsyncTask для вызова нового потока и в методе OnPostExecute, диалоге сообщений на вызов шоу.

1

Класс ваших вычислений должен расширять SwingWorker. Вы делаете ваши расчеты в doInBackground()

public class Calculations extends SwingWorker<Void, Void>{ 

    @Override 
    protected Void doInBackground() throws Exception { 
     System.out.println("Calculating."); 
     Thread.sleep(3000); 
     return null; 
    } 
} 

И в ваших actionPerformed() вы используете расчеты, как это.

public void actionPerformed(ActionEvent e) 
    { 
     //FISRT run method 
     Calculations a = new Calculations(); 
     a.execute(); // Start calculations 
     try { 
     a.get(); // Wait for calculations to finish 
     } catch (InterruptedException | ExecutionException e1) { 
     e1.printStackTrace(); 
     } 
     //THEN inform that just finished 
     JOptionPane.showMessageDialog(null,"just finished"); 
    } 

EDIT: Если у вас есть несколько методов, которые вы хотели бы работать в SwingWorker вы можете сохранить ваш код почти как она есть. Но добавьте только эти строки.

public class Calculations{ 
    protected void calculate() { 
     SwingWorker sw = new SwingWorker(){ 
      @Override 
      protected Object doInBackground() throws Exception { 
       System.out.println("Calculating."); 
       Thread.sleep(3000); 
       return null; 
      } 
     }; 
     sw.execute(); //Start 
     try { 
      sw.get(); //Wait 
     } catch (InterruptedException | ExecutionException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

В каждом методе Calculations вы создаете новый SwingWorker как вы сделали, и ждать его, чтобы закончить по телефону SwingWorker.get();

+0

Если я не могу использовать extends SwingWorker , потому что класс Calculations имеет другой методы, кроме «doCaculations();»? – geo

+0

См. Отредактированный ответ. –

+0

Спасибо за ваш ответ. Я изменил свой код, используя ваши предложения. Он вызывает всплывающее диалоговое окно сообщения, когда метод doCaculations() заканчивается, но пока что индикатор выполнения не обновляется, как это должно быть сделано. Он просто переходит на 100%, когда doCaculations() заканчивается – geo

Смежные вопросы