开发者

Batch-updating JComponents. Need suggestions for a better (threaded) design

I have a GUI in which some groups of JComponents get "batch-updated", i.e., I have a loop and for almost every iteration of the loop, I need to update these JComponents. So, I tried to do the updates alongside the computations in the loop but it didn't go well being that, (if I interpret correctly) the updates were "slowed down" by the computations, the effect being only the last update became perceptible to the user.

That's when I thought of p开发者_C百科utting all update-related code on a separate thread. First off, I created an interface called UpdatableComponent which will wrap all JComponents that must be updated:

public interface UpdatableComponent {
/**
 * Implementors should be the one responsible for typecasting update
 * into the appropriate objects.
 */
public void update(Object update);
}

So if, for instance, I want to update a 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);
    }
}

Then, my Runnable class for threading:

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++){

    }
}

}

And this is where I hit a snag. How do I know what argument to pass for each UpdatableComponent's update method? I thought of maintaining an Object array, arguments, which will map an UpdatableComponent to an argument for its update method (I have a setter method for it, of course). But then that would be (1) too tightly-coupled---bad design!---and (2) too much for a thread; the loop inside run will continuously call update on each UpdatableComponent, giving it its designated argument, updating regardless whether it actually updated or not.

I can't help but feel that I may have missed a simple way to do it. Any suggestion/advice will be very welcome. Thank you.


It sound like a SwingWorker is what you are looking for. The computation is done inside the method doInBackground(), results are publish()ed and process() then updates the components.


this issue has to do with Concurrency in Swing, there is described other basic stuff and including @Howard +1 suggestion about SwingWorker

for Runnable#Thread works,

public void update(Object update) {
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            l.setText((String) update);
        }
    });
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜