2012-06-10 59 views
2

我有一個按鈕單擊事件,將觸發一個擺動工作線程,該線程作爲回報激發另一個線程進行長時間計算,包括寫入文件。然後讀取該文件以繪製一些圖形。然而繪製如果我不添加之間的延遲部分永遠不會發生。(它說沒有找到文件,雖然文件是there..What是更好的辦法來解決這一問題而不增加延遲..擺動工人延遲

private void buttonFragmentActionPerformed(java.awt.event.ActionEvent evt) {            
    try 
    { 
     ESIPlusFragmenterWorker epfw = new ESIPlusFragmenterWorker(10, sdfFile, cidSpectrum); 
     epfw.execute(); 

     Thread.sleep(1000); 

     holder.molTable1.drawMolViewPanel(currDir+sep+"esiFragments"+sep+"esiFrag.sdf"); 
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
} 

搖擺工人

public class ESIPlusFragmenterWorker extends SwingWorker<Void, Void>{ 

int mzppm_; 
String SDF_; 
String spectrum_; 
Double mion_; 
MolTable holder_; 

ESIPlusFragmenterWorker(int mzppm, String SDF, String spectrum) 
{ 
    mzppm_ = mzppm; 
    SDF_ = SDF; 
    spectrum_ = spectrum; 
} 

@Override 
protected Void doInBackground() { 
    try 
    { 
    Molecule mol; 
    MolImporter importer = new MolImporter(SDF_); 
    ExecutorService te = Executors.newFixedThreadPool(1); 
    while ((mol = importer.read()) != null) 
    { 
    Runnable epf = new ESIPlusFragmenter(mol, spectrum_, mzppm_); 
    Thread t = new Thread(epf); 
    te.execute(epf); 
    } 
    importer.close(); 
    te.awaitTermination(10, TimeUnit.MINUTES); 
    } 
    catch (Exception e) 
    { 
     // 
    } 
    finally 
    { 
     return null; 
    } 
} 


@Override 
protected void done() { 
    try { 
     // 
    } catch (Exception e) { 
     //e.printStackTrace(); 
    } 
} 

}

回答

2

永遠,永遠,永遠不會調用Thread.sleep(...)在EDT,因爲這將使您的整個GUI睡覺了。再說,如果你估計錯了,後臺進程需要更長的時間比你的睡眠延遲時間?

一種可能的解決方案是將PropertyChangeListener添加到SwingWorker,並監聽SwingWorker.StateValue的「state」屬性爲SwingWorker.StateValue.DONE,然後執行繪製。

例如

private void buttonFragmentActionPerformed(java.awt.event.ActionEvent evt) { 
    try { 
    ESIPlusFragmenterWorker epfw = new ESIPlusFragmenterWorker(10, 
      sdfFile, cidSpectrum); 
    epfw.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent pcEvt) { 
      if ("state".equals(pcEvt.getPropertyName())) { 
       if (pcEvt.getNewValue().equals(SwingWorker.StateValue.DONE)) { 
       holder.molTable1.drawMolViewPanel(currDir + sep 
         + "esiFragments" + sep + "esiFrag.sdf"); 
       } 
      } 
     } 
    }); 
    epfw.execute(); 

所以這樣做是等待SwingWorker完成其業務,然後再調用偵聽器中的代碼。

另一種方法是在SwingWorker的done()方法內調用holder.molTable1.drawMolViewPanel,這也可以工作,但通過使用PropertyChangeListener來完成上述操作,SwingWorker不必具備任何有關代碼在監聽器中調用(而不是使用SwingWorker的done()方法),這可能允許更鬆散的耦合。

+1

+1這是一個好得多的答案,然後是我想到的一行。 – Robin

+0

@Robin:謝謝! –

+0

感謝您的詳細答案..但是,這種方法沒有奏效。我想知道這個問題是否在其他地方..我正在給這個問題增加一個swing工人類。 – lochi