Как можно преодолеть исключение одновременной модификации в посреднике GUI? - PullRequest
3 голосов
/ 05 февраля 2011

К вашему сведению Я принял шаблон посредника для моего графического интерфейса в Swing на Java.

К сожалению, исключение одновременной модификации всегда генерируется, если пользовательский ввод требует нового окна.

Это потому, что мой код пытается добавить нового коллегу (новое окно) в список коллег посредника в процессе обработки пользовательского ввода от существующего коллеги (окна).

например.

public MainScreenColleague implements GuiColleague, ActionListener {
    private GuiMediator mediator;
    public MainScreenColleague(GuiMediator medi) {
        mediator = medi;
        // implement JFrame with JButtons
    }
    public conveyInputToMediator(EventObject event) {
        mediator.conveyInputToColleagues(event);
    }
    public receiveInputFromMediator(EventObject event) {
        if (event.getSource() = particularBtn) {
            GuiColleague particularColleague = new ParticularConcreteColleague(mediator);
            //THIS IS THE CODE THAT THROWS CONCURRENCY EXCEPTION
            mediator.addGuiColleague(particularColleague);
        }       
}

Есть ли какая-то другая структура обработки добавления новых коллег, которую я могу усыновить? Заранее спасибо за любые предложения или идеи.

Ответы [ 2 ]

1 голос
/ 05 февраля 2011

Если количество обходов значительно превышает количество модификаций, может подходить структура данных копирования при записи, например CopyOnWriteArrayList .

1 голос
/ 05 февраля 2011

Один из вариантов может заключаться в принятии модели Swing-esque и в том, чтобы ваш посредник сохранял «очередь событий» обновлений, которые он должен сделать, когда придет время.Таким образом, когда вы добавляете новые окна во время обработки событий от какого-либо другого объекта, это окно не сбивает логику.Он просто добавляется в очередь «обрабатывать это, когда вы закончите», которая обрабатывается после завершения передачи.

Другой вариант - сделать копию списка перед его итерацией, чтобы изменениясделанные в необработанной структуре во время итерации, не отображаются в списке, который повторяется.

Еще одной идеей было бы использование некоторой неитераторской техники для посещения элементов.Например, если у вас есть окна, сохраненные в списке, вы можете использовать цикл for, подобный следующему:

for (int i = 0; i < elems.size(); ++i)
    /* ... */

, который не будет генерировать подобные исключения.

...