Синхронизация редактора GEF с моделью EMF с помощью двух адаптеров EMF

У меня возникли проблемы с синхронизацией моего редактора GEF с моделью на основе EMF. Я думаю, это связано с тем, что адаптер EMF, встроенный в модель, или, скорее, методы, которые он вызывает, не завершены до того, как адаптер редактора notifyChanged() вызывается и обновляет дочерние элементы модели. Это приводит к тому, что представление редактора не синхронизируется с самой моделью, или, скорее, изменения в модели не отображаются в представлении, когда должны быть.

Рассмотрим эту установку. Command "CreateNodeCommand" добавляет узел к базовой модели:

@Override
public void execute() {
...
getNewNode().setGraph(getGraph());
...
}

GraphEditPart имеет внутренний класс, расширяющий org.eclipse.emf.common.notify.Adapter. Это метод notifyChanged() действительно уведомлен, как показано ниже (неполный код):

@Override
public void notifyChanged(Notification notification) {
  switch (notification.getEventType()) {
case Notification.ADD:
      System.err.println("ADD occurred!");
  refreshChildren();
}

Проблема в том, что сама (сторонняя) модель также реализует Adapter, который, в свою очередь, запускает ряд методов для нового элемента модели, таких как добавление идентификатора и т. д.

Мне кажется, что тот факт, что фигура нового элемента не появляется в редакторе сразу после его создания, а только после следующего шага редактирования, фигура которого потом не появляется, говорит о том, что адаптер модели все еще занят настройкой нового элемента, в то время как refreshChildren() уже вызывается адаптером editor.

Похоже, это требует синхронизации, но я не уверен, можно ли этого добиться с помощью встроенных функций Java для многопоточности или же требуется подход на основе EMF.

Пожалуйста, поделитесь своими знаниями о синхронизации в EMF.

Спасибо заранее!

РЕДАКТИРОВАТЬ

По запросу вот исходный код метода getModelChildren():

@Override 
protected List<EObject> getModelChildren() {
  List<EObject> allModelObjects = new ArrayList<EObject>();
  allModelObjects.addAll(((MyGraph) getModel()).getTokens());
  allModelObjects.addAll(((MyGraph) getModel()).getNodes());
  return allModelObjects;
}

person s.d    schedule 20.08.2012    source источник
comment
Не могли бы вы немного подробнее рассказать о модели? Я не мог понять, если у вас есть одна модель или две.   -  person vainolo    schedule 20.08.2012
comment
@vainolo: Это одна модель, основанная на EMF (довольно) универсальная графовая модель. Эта модель реализует Adapter для прослушивания изменений внутри себя. Кажется, моя проблема заключается в том, что Adapter, который я использую в своем редакторе, уведомляется до того, как действия, вызванные внутренним Adapter модели, завершатся, поэтому элемент, похоже, был создан, но (я думаю) еще не добавлен внутри модели в список, который я использую для getChildren().   -  person s.d    schedule 27.08.2012
comment
Я не мастер EMF, но мне кажется странным, что вы получаете уведомление до того, как изменение завершено. Может быть, вас уведомляют о другом изменении?   -  person vainolo    schedule 28.08.2012
comment
@vainolo: Да, я подумал, что это будет странно. Но это это уведомление ADD. По крайней мере, я получаю стандартное сообщение. Я предполагаю, что метод модели должен сначала добавить элемент, затем изменить его (?) по мере необходимости, а затем добавить его в список элементов, которые вызывает getModelChildren().   -  person s.d    schedule 28.08.2012
comment
Можете ли вы опубликовать код getModelChildren? Если модель генерируется из EMF, то нет возможности, чтобы дочерние элементы не находились в модели, когда вы уведомлены.   -  person vainolo    schedule 29.08.2012
comment
@vainolo: Спасибо, я добавил код в вопрос. Может ли это иметь какое-то отношение к защищаемому методу?   -  person s.d    schedule 29.08.2012
comment
Странно... Вроде все нормально. Знаете ли вы, был ли изменен код для setGraph из сгенерированного кода? Я прочитал сгенерированный код, который у меня есть, используя EMF, и уведомления отправляются только ПОСЛЕ того, как все изменения в модели внесены. Я думаю, вам понадобится очень долгий сеанс отладки, чтобы понять, что происходит :-(   -  person vainolo    schedule 30.08.2012
comment
@vainolo: Оказывается, никто не мог бы мне в этом помочь, ср. мой ответ. Д'ух! Так что разработчики модели любезно перенесли эту строчку для меня, и теперь она работает :).   -  person s.d    schedule 11.09.2012
comment
Это было сделано специально? они знают почему? потому что если нет, может быть, что-то еще сломается   -  person vainolo    schedule 11.09.2012
comment
@vainolo: Это было сделано не специально. Я предполагаю, что модифицировал сгенерированный код и просто добавил логику после вызова. Они никогда не предполагали, что модель будет использоваться в GEF/другом графическом приложении, поэтому я думаю, что они просто не обращали внимания на какие-либо проблемы...   -  person s.d    schedule 11.09.2012


Ответы (2)


Отлаживая (стороннюю) модель, я обнаружил, что Graph enotify() отправил уведомление до того, как произошло фактическое добавление, поэтому мой Adapter получил уведомление слишком рано, т. Е. До того, как узел был добавлен.

Уведомление теперь вызывается после добавления и все работает нормально.

Спасибо за всю твою помощь!

person s.d    schedule 11.09.2012

Попробуйте расширить EContentAdapter вместо AdapterImpl и не забудьте вызвать

super.notifyChanged(Notification notification);

в этом. Это адаптер, который будет добавляться к новым элементам модели и уведомлять вас об их изменении.

person execc    schedule 22.08.2012
comment
Спасибо. Я попробую EContentAdapter. - person s.d; 27.08.2012
comment
EContentAdapter работает нормально, но не решает проблему. Похоже, что это действительно это проблема с синхронизацией. - person s.d; 28.08.2012