title: GEF + EMF: Why doesn't my editor remove the Figure for a removed object when refreshChildren() is called?
body: <p>I have implemented a GEF editor for a graph-like EMF model, with a remove command for a certain type of node in the graph. I think I've done all the necessary steps in order to make this set up work (<a href="https://stackoverflow.com/users/817399/vainolo">vainolo</a>'s <a href="http://www.vainolo.com/tag/gef/" rel="nofollow noreferrer">blog</a> has been a great help).</p>
  
  <p>However, when I'm deleting a model element, the <strong>view doesn't get refreshed</strong>, i.e., the figure for the model element isn't removed from the editor view, and I have no idea why. I'd be extremely grateful if somebody could have a look at my sources and point me to any problems (and possibly solutions :)). Many thanks in advance!</p>
  
  <p><em>Below are what I think are the important classes for this issue. Please do let me know should I add further code/edit the code, etc. (I've left out code that I thought doesn't help, e.g., getters and setters, class variables). Thanks!</em></p>
  
  <p><strong>DiagramEditPart</strong></p>
  
  <pre class="lang-java prettyprint-override"><code>public class DiagramEditPart extends AbstractGraphicalEditPart {
  
      public DiagramEditPart(Diagram model) {
          this.setModel(model);
          adapter = new DiagramAdapter();
      }
  
      @Override protected IFigure createFigure() {
          Figure figure = new FreeformLayer();
          return figure;
        }
  
        @Override protected void createEditPolicies() {
          installEditPolicy(EditPolicy.LAYOUT_ROLE, new DiagramXYLayoutPolicy());
        }
  
        @Override protected List&lt;EObject&gt; getModelChildren() {
            List&lt;EObject&gt; allModelObjects = new ArrayList&lt;EObject&gt;();
            if (((Diagram) getModel()).getMyNodes() != null)
            allModelObjects.addAll(((Diagram) getModel()).getMyNodes());
            return allModelObjects;
        }
  
        @Override public void activate() {
            if(!isActive()) {
                ((Diagram) getModel()).eAdapters().add(adapter);
            }
            super.activate();
        }
  
  
        @Override public void deactivate() {
            if(isActive()) {
                ((Diagram) getModel()).eAdapters().remove(adapter);
            }
            super.deactivate();
        }
  
      public class DiagramAdapter implements Adapter {
  
            @Override public void notifyChanged(Notification notification) {
                switch (notification.getEventType()) {
              case Notification.REMOVE: refreshChildren();
                  break;
              default:
                  break;
              }
            }
  
            @Override public Notifier getTarget() {
                return (Diagram) getModel();
            }
  
            @Override public void setTarget(Notifier newTarget) {
                // Do nothing.
            }
  
            @Override public boolean isAdapterForType(Object type) {
                return type.equals(Diagram.class);
            } 
  
        }
  
  }
  </code></pre>
  
  <p><strong>MyNodeEditPart</strong></p>
  
  <pre class="lang-java prettyprint-override"><code>public class MyNodeEditPart extends AbstractGraphicalEditPart {
  
      public MyNodeEditPart(MyNode model) {
           this.setModel(model);
           adapter = new MyNodeAdapter();
      }
  
      @Override protected IFigure createFigure() {
          return new MyNodeFigure();
      }
  
      @Override protected void createEditPolicies() {
          installEditPolicy(EditPolicy.COMPONENT_ROLE, new MyNodeComponentEditPolicy());
      }
  
      @Override protected void refreshVisuals() {
          MyNodeFigure figure = (MyNodeFigure) getFigure();
          DiagramEditPart parent = (DiagramEditPart) getParent();
          Dimension labelSize = figure.getLabel().getPreferredSize();
          Rectangle layout = new Rectangle((getParent().getChildren().indexOf(this) * 50), 
                  (getParent().getChildren().indexOf(this) * 50), (labelSize.width + 20), 
                  (labelSize.height + 20));
          parent.setLayoutConstraint(this, figure, layout);
      }
  
      public List&lt;Edge&gt; getModelSourceConnections() {
          if ((MyNode) getModel() != null &amp;&amp; ((MyNode) getModel()).getDiagram() != null) {
              ArrayList&lt;Edge&gt; sourceConnections = new ArrayList&lt;Edge&gt;();
              for (Edge edge : ((MyNode) getModel()).getDiagram().getOutEdges(((MyNode) getModel()).getId())) {
                  sourceConnections.add(edge);
              }
              return sourceConnections;
          }
          return null;
      }
  
      // + the same method for targetconnections
  
      @Override public void activate() {
          if (!isActive()) {
              ((MyNode) getModel()).eAdapters().add(adapter);
          }
          super.activate();
      }
  
      @Override public void deactivate() {
          if (isActive()) {
              ((MyNode) getModel()).eAdapters().remove(adapter);
          }
          super.deactivate();
      }
  
      public class MyNodeAdapter implements Adapter {
  
          @Override
          public void notifyChanged(Notification notification) {
              refreshVisuals();
          }
  
          @Override
          public Notifier getTarget() {
              return (MyNode) getModel();
          }
  
          @Override
          public void setTarget(Notifier newTarget) {
              // Do nothing
          }
  
          @Override
          public boolean isAdapterForType(Object type) {
              return type.equals(MyNode.class);
          }
  
      }
  
  }
  </code></pre>
  
  <p><strong>MyNodeComponentEditPolicy</strong></p>
  
  <pre class="lang-java prettyprint-override"><code>public class MyNodeComponentEditPolicy extends ComponentEditPolicy {
  
      @Override
      protected Command createDeleteCommand(GroupRequest deleteRequest) {
          DeleteMyNodeCommand nodeDeleteCommand = new DeleteMyNodeCommand((MyNode) getHost().getModel());
          return nodeDeleteCommand;
      }
  
  }
  </code></pre>
  
  <p><strong>DeleteMyNodeCommand</strong></p>
  
  <pre class="lang-java prettyprint-override"><code>public class DeleteMyNodeCommand extends Command {
  
      public DeleteMyNodeCommand(MyNode model) {
          this.node = model;
          this.graph = node.getDiagram();
      }
  
      @Override public void execute() {
          getMyNode().setDiagram(null);
          System.out.println("Is the model still present in the graph? " + getGraph().getMyNodes().contains(getMyNode())); 
              // Returns false, i.e., graph doesn't contain model object at this point!
      }
  
      @Override public void undo() {
          getMyNode().setDiagram(getGraph());
      }
  
  }
  </code></pre>
  
  <hr>
  
  <h2>EDIT</h2>
  
  <p>Re execc's comment: Yes, <code>refreshChildren()</code> is being called. I've tested this by overriding it and adding a simple <code>System.err</code> line, which is being displayed on the console on deletion of a node:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Override
  public void refreshChildren() {
      super.refreshChildren();
      System.err.println("refreshChildren() IS being called!");
  }
  </code></pre>
  
  <hr>
  
  <h2>EDIT 2</h2>
  
  <p>The funny (well...) thing is, when I close the editor and persist the model, then re-open the same file, the node isn't painted anymore, and is not present in the model. But what does this mean? Am I working on a stale model? Or is refreshing/getting the model children not working properly?</p>
  
  <hr>
  
  <h2>EDIT 3</h2>
  
  <p>I've just found a peculiar thing, which <em>might</em> explain the isues I have? In the <code>getModelChildren()</code> method I call <code>allModelObjects.addAll(((Diagram) getModel()).getMyNodes());</code>, and <code>getMyNodes()</code> returns an <strong>unmodifiable</strong> <code>EList</code>. I found out when I tried to do something along the lines of <code>((Diagram) getModel()).getMyNodes().remove(getMyNode())</code> in the delete command, and it threw an <code>UnsupportedOperationException</code>... Hm.</p>
  
  <hr>
  
  <h2>EDIT 4</h2>
  
  <p>Er, <a href="http://www.youtube.com/watch?v=Nfrk2UdEOcQ&amp;feature=fvwrel" rel="nofollow noreferrer">somebody kill me please</a>? 
  I've double-checked whether I'm handling the same <code>Diagram</code> object at all times, and while doing this I stumbled across a very <strong>embarassing</strong> thing: </p>
  
  <p>The <code>getModelChildren()</code> method in <code>DiagramEditPart</code> in the last version read approx. like this:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Override protected List&lt;EObject&gt; getModelChildren() {
      List&lt;EObject&gt; allModelObjects = new ArrayList&lt;EObject&gt;();
      EList&lt;MyNode&gt; nodes = ((Diagram) getModel()).getMyNodes();
      for (MyNode node : nodes) {
          if (node.getDiagram() != null); // ### D'Uh! ###
              allModelObjects.add(node);
      }
      return allModelObjects;
   }
  </code></pre>
  
  <p>I'd like to apologize for stealing everyone's time! Your suggestions were very helpful, and indeed helped my to finally track down the bug!</p>
  
  <p>I've also learned a number of lessons, amongst them: Always paste the original code, over-simplifaction may cloak your bugs! And I've learned a lot about EMF, <code>Adapter</code>, and GEF. Still:</p>
  
  <p><img src="https://i.stack.imgur.com/IiXye.jpg" alt="enter image description here"></p>