2014-02-14 91 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()方法更新。

我試圖讓線程在線程完成後線程運行的方式工作。但我無法讓它工作。會發生什麼是彈出消息立即彈出(這意味着它是線程運行之前,我希望它運行)。

注意:「剛完成」消息只是爲了測試代碼。在我的「真實」程序中,一個方法就在它的位置上。我正在做這個筆記,因爲如果我只是想要一個消息顯示我可以將它放在doCaculations()方法的末尾,並且一切都會正常工作。

我知道我必須在線程處理方面做錯了,但是我找不到它。有任何想法嗎?

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

我用於分類計算「繼承Thread」,以使用join方法上,但沒有什麼變化。你能提供更多細節嗎? – 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"); 
    } 

編輯:如果您有多個方法,您想在一個運行的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

如果我不能使用擴展SwingWorker ,因爲類Calculations有其他除了'doCaculations()'之外的方法? – geo

+0

查看編輯答案。 –

+0

感謝您的回答。我使用你的建議修改了我的代碼。它確實會在doCaculations()方法完成時彈出消息對話框,但同時進度條並未像原本應該那樣更新。當doCaculations()完成時,它跳到100% – geo

相關問題