Пакетное обновление JComponents. Нужны предложения для лучшего (резьбового) дизайна - PullRequest
1 голос
/ 03 сентября 2011

У меня есть графический интерфейс, в котором некоторые группы 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, arguments, который сопоставит UpdatableComponent с аргументом для его метода обновления (у меня, конечно, есть метод setter). Но тогда это будет (1) слишком тесно связано - плохой дизайн! --- и (2) слишком много для потока; цикл внутри выполнения будет непрерывно вызывать update для каждого UpdatableComponent, предоставляя ему назначенный аргумент, обновляя независимо от того, действительно ли он обновлен или нет.

Я не могу помочь, но чувствую, что, возможно, упустил простой способ сделать это. Любое предложение / совет будет очень кстати. Спасибо.

Ответы [ 2 ]

5 голосов
/ 03 сентября 2011

Звучит как SwingWorker - это то, что вы ищете. Вычисление выполняется внутри метода doInBackground(), результаты publish() ed и process(), затем обновляются компоненты.

3 голосов
/ 04 сентября 2011

эта проблема связана с Параллелизмом в Swing , здесь описаны другие основные вещи, включая @Howard +1 предложение о SwingWorker

для Runnable#Thread работ,

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

        @Override
        public void run() {
            l.setText((String) update);
        }
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...