我有一个按钮点击事件,它将触发一个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();
}
}
摇摆工人
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();
}
}
}
答案 0 :(得分:2)
从不,永远不要在EDT上调用Thread.sleep(...)
因为这会让你的整个GUI都处于睡眠状态。此外,如果您估计错误,后台进程需要的时间比您的睡眠延迟时间长?
一种可能的解决方案是将一个PropertyChangeListener添加到SwingWorker并监听SwingWorker.StateValue的“state”属性为SwingWorker.StateValue.DONE,然后进行绘制。
e.g。
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()
方法相反),这可能允许更松散的耦合。