java - Swing worker 延迟

标签 java swing swingworker

我有一个按钮单击事件,它将触发一个 Swing 工作线程,而该线程又会触发另一个线程来进行长时间计算,包括写入文件。然后读取这个文件来绘制一些图形。但是,如果我不在中间添加延迟,绘图部分永远不会发生。(它说找不到文件,尽管文件在那里。在不添加延迟的情况下修复此问题的更好方法是什么。

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

Swing worker

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

}

最佳答案

永远,永远,永远不要打电话 Thread.sleep(...)在 EDT 上,因为这将使您的整个 GUI 进入休眠状态。另外,如果你估计错误,后台进程花费的时间比你的 sleep 延迟时间长怎么办?

一种可能的解决方案是向 SwingWorker 添加 PropertyChangeListener 并监听 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() 方法相反),并且这可能允许更松散的耦合。

关于java - Swing worker 延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10968846/

相关文章:

java - JButton ActionListener - 仅在单击 JButton 后更新 GUI

java - 如何使JTextPane达到一张纸的大小?

java - Swing 工作线程不并发

java - 使用HttpClient进行登录认证

java - Tomcat:外部 JVM 配置

java - 将 JList 添加到 JPanel 与 JLabel 不同(除了明显的之外),为什么?

JavaFX 和 Swing 颜色不匹配

java - 使用 Swing 的多线程

java - 为什么 "IGNITE"计算的字段返回 "BIGINT"类型?理论上应该是 "DECIMAL"类型,因为结果包含十进制数字

java - Zest 中的坐标导出