批量更新JComponents。需要有关更好(线程)设计的建议

时间:2011-09-03 19:37:58

标签: java multithreading swing

我有一个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上的更新,为其指定参数,无论是否实际更新都会更新。

我不禁觉得我可能错过了一个简单的方法。任何建议/意见将非常欢迎。谢谢。

2 个答案:

答案 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);
        }
    });
}