Question
我在使用Swingworker时出现了进度条不更新的问题。该功能是先从数据库中查询到数据结果集,然后在JTable中进行显示,进度条显示的是在JTable中进行显示的进度。下面是简化后的关键代码:
class TestSwingWorker extends SwingWorker<Integer,Integer>{
private JLabel status; //显示进度文字
private JProgressBar jpb; //进度条
...
@Override
protected Integer doInBackground() throws Exception {
...
for(int i=0;i<vectors.size();i++){ //vectors是查询到的数据结果集
//显示到JTable
...
//发送进度
publish(i+1);
}
...
@Override
protected void process(List<Integer> chunks) {
int x = chunks.get(0);
status.setText("操作完成进度:"+x);
jpb.setValue(x); //显示进度
}
}
}
原因
查看SwingWorker的publish方法,可以看到它实际上是通过向EDT线程发送AccumulativeRunnable任务来执行process方法:
//SwingWorker.publish
protected final void publish(V... chunks) {
synchronized (this) {
if (doProcess == null) {
doProcess = new AccumulativeRunnable<V>() {
@Override
public void run(List<V> args) {
//调用process
process(args);
}
@Override
protected void submit() {
doSubmit.add(this);
}
};
}
}
doProcess.add(chunks);
}
//SwingWorker.process 在EDT中调用
protected void process(List<V> chunks) {
}
在我的代码中,之所以没有显示进度,就是因为publish方法执行得太快,导致EDT线程无法及时接受其发送的任务,从而无法执行process。