我有一个GUI,其中一些JComponents组得到“批量更新”,即我有一个循环,并且几乎循环的每次迭代,我需要更新这些JComponents。所以,我试着在循环中的计算中进行更新,但它并不顺利,(如果我正确解释)更新被计算“减慢”,效果只是最后更新变得易于被用户感知。
那时我想把所有与更新相关的代码放在一个单独的线程上。首先,我创建了一个名为UpdatableComponent的接口,它将包装所有必须更新的JComponents:
public interface UpdatableComponent {
/**
* Implementors should be the one responsible for typecasting update
* into the appropriate objects.
*/
public void update(Object update);
}
因此,例如,如果我想更新JLabel
public class UpdatableJLabel implements UpdatableComponent{
private JLabel l;
public UpdatableJLabel(JLabel l){
this.l = l;
}
public void update(Object update){
l.setText((String) update);
}
}
然后,我的Runnable类用于线程化:
public class UIUpdateRunnable implements Runnable {
private UpdatableComponent[] forUpdating;
public UIUpdateRunnable(UpdatableComponent[] uc) {
forUpdating = uc;
}
public void run() {
int limit = forUpdating.length;
for(int i = 0; i < limit; i++){
}
}
}
这就是我遇到麻烦的地方。我如何知道每个UpdatableComponent的更新方法传递什么参数?我想维护一个Object数组,参数,它会将UpdatableComponent映射到其更新方法的参数(当然我有一个setter方法)。但那会是(1)太紧密耦合---糟糕的设计!---和(2)太多的线程;运行中的循环将连续调用每个UpdatableComponent上的更新,为其指定参数,无论是否实际更新都会更新。
我不禁觉得我可能错过了一个简单的方法。任何建议/意见将非常欢迎。谢谢。
答案 0 :(得分:5)
听起来像SwingWorker就是你要找的东西。计算在方法doInBackground()
内完成,结果为publish()
ed process()
然后更新组件。
答案 1 :(得分:3)
此问题与Concurrency in Swing有关,其中介绍了其他基本内容,包括@Howard
+1关于SwingWorker
for Runnable#Thread
有效,
public void update(Object update) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
l.setText((String) update);
}
});
}