Question

I'm having trouble synchronising my GEF editor with the EMF-based model. I think this is due to the fact that the model-internal EMF Adapter, or rather the methods it calls, aren't finished before the editor's Adapter's notifyChanged() is called and updates the model children. This leads to the editor view being out-of-sync with the model itself, or rather, the changes to the model not being represented in the view when they should be.

Consider this set up. A Command "CreateNodeCommand" adds a node to the underlying model:

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

The GraphEditPart has an internal class extending org.eclipse.emf.common.notify.Adapter. It's notifyChanged() method is indeed notified, as tested similar to below (incomplete code):

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

The problem is, that the (third-party) model itself also implements an Adapter, which in turn runs a number of methods on the new model element, such as adding an ID, etc.

It seems to me that the fact that the new element's figure doesn't show up in the editor directly after it's been created - but only after the next editing step, the figure for which then doesn't appear - suggests that the model adapter is still busy setting up the new element while refreshChildren() is already being called by the editor adapter.

This seems to call for synchronisation, but I'm unsure whether this can be achieved with built-in Java functionality for multithreading, or calls for an EMF-based approach.

Please share your knowledge about synchronising in EMF.

Many thanks in advance!

EDIT

On request, here is the source code for the getModelChildren() method:

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

Solution

Debugging the (3rd party) model, I found out that the Graph's enotify() fired the notification before the actual adding took place, hence my Adapterreceived the notification too early, i.e., before the node had been added.

The notification is now called after the add and everything works fine.

Thanks for all of your help!

OTHER TIPS

Try extending EContentAdapter instead of AdapterImpl, and not forget to call

super.notifyChanged(Notification notification);

in it. It's an adapter, which will add itself to new elements of the model, and notify you then they are changed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top