【问题标题】:Swing Worker Delay摆动工人延迟
【发布时间】:2012-06-10 12:50:22
【问题描述】:

我有一个按钮单击事件,该事件将触发一个摆动工作线程,该线程作为回报触发另一个线程进行长时间计算,包括写入文件。然后读取这个文件来绘制一些图形。但是,如果我不在两者之间添加延迟,则绘图部分永远不会发生..(它说文件未找到,尽管文件在那里..有什么更好的方法可以在不增加延迟的情况下解决这个问题..

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

}

【问题讨论】:

    标签: java swing swingworker


    【解决方案1】:

    永远,永远,永远不要在 EDT 上调用 Thread.sleep(...),因为这会使您的整个 GUI 进入睡眠状态。另外,如果你估计错了,后台进程比你的睡眠延迟时间长怎么办?

    一种可能的解决方案是将 PropertyChangeListener 添加到 SwingWorker 并侦听 SwingWorker.StateValue 的“状态”属性为 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 这比我想的单线答案要好得多。
    • 感谢您的详细回答。但是这种方法不起作用。我想知道问题是否出在其他地方。我正在为问题添加摇摆工人类。
    • 好吧..我是个白痴..我忘了关闭线程执行器..te.shutdown();在 te.awaitTermination(10, TimeUnit.MINUTES);之前解决了这个问题。感谢您提供出色的详细答案。
    • @lochi:不客气,很高兴你的工作顺利!
    猜你喜欢
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 2011-08-05
    • 1970-01-01
    • 2012-01-02
    • 2017-11-17
    相关资源
    最近更新 更多