2

スイングワーカースレッドを起動するボタンクリックイベントがあり、その代わりに別のスレッドを起動して、ファイルの書き込みを含む長い計算を実行します。次に、このファイルを読み取ってグラフィックを描画します。ただし、間に遅延を追加しないと、描画部分は発生しません。(ファイルは存在しますが、ファイルが見つかりません。遅延を追加せずにこれを修正するためのより良い方法は何ですか。

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

}

4

1 に答える 1

2

Thread.sleep(...)GUI全体がスリープ状態になるため、EDTを呼び出さないでください。さらに、見積もりが間違っていて、バックグラウンドプロセスが睡眠遅延時間よりも長くかかる場合はどうなりますか?

考えられる解決策の1つは、PropertyChangeListenerをSwingWorkerに追加し、SwingWorker.StateValueがSwingWorker.StateValue.DONEになるように「state」プロパティをリッスンしてから、描画を行うことです。

例えば

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のメソッド内でholder.molTable1.drawMolViewPanelを呼び出すことです。done()これも機能しますが、上記のようにPropertyChangeListenerを使用して行うことにより、SwingWorkerはで呼び出されたコードに関する知識を持っている必要はありません。リスナー(SwingWorkerのdone()メソッドを使用するのとは対照的に)、これにより、より緩い結合が可能になる場合があります。

于 2012-06-10T12:52:45.540 に答える