Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » GEF » Reliably remove Connection figures with orphan EditParts on deletion of model?
icon9.gif  Reliably remove Connection figures with orphan EditParts on deletion of model? [message #1016992] Fri, 08 March 2013 09:06 Go to next message
Stephan Druskat is currently offline Stephan Druskat
Messages: 52
Registered: October 2011
Location: Berlin, Germany
Member

Assume the following simplified EMF model structure:
    Graph
    /   \
 Node   Edge


In my GEF editor, the EditParts are organized as follows.

GraphEditPart (Figure = FreeformLayer) excerpt
@Override
protected List<EObject> getModelChildren() {
  List<EObject> childrenList = new ArrayList<EObject>();
  Graph graph = (Graph) getModel();childrenList.addAll(graph.getNodes());
  return childrenList;
}


NodeEditPart (Figure = extending Figure) excerpt (also showing how Edges for which a Node is source or target are got)
@Override
protected List<Edge> getModelSourceConnections() {
  Node node = (Node) getModel();
  Graph graph = node.getGraph();
  String nodeId = node.getId();
  List<Edge> sourceList = new ArrayList<Edge>();
  if (graph != null)
    sourceList.addAll(graph.getOutEdges(nodeId));
  return sourceList;
}

@Override
protected List<Edge> getModelTargetConnections() {
  // Same principle as getModelSourceConnections
}


Editor class excerpt (in case it matters)
@Override
protected void initializeGraphicalViewer() {
  super.initializeGraphicalViewer();
  GraphicalViewer viewer = getGraphicalViewer();
  viewer.setContents(graph);
  ScalableFreeformRootEditPart root = (ScalableFreeformRootEditPart) viewer.getRootEditPart();
  ConnectionLayer connLayer = (ConnectionLayer) root.getLayer(LayerConstants.CONNECTION_LAYER);
  GraphicalEditPart contentEditPart = (GraphicalEditPart) root.getContents();
  ShortestPathConnectionRouter shortestPathConnectionRouter = new ShortestPathConnectionRouter(contentEditPart.getFigure());
  connLayer.setConnectionRouter(shortestPathConnectionRouter);
}


All EditParts have their own adapter (extending org.eclipse.emf.ecore.util.EContentAdapter or implementing org.eclipse.emf.common.notify.Adapter).

This results in an EditPart structure, where NodeEditParts are children of the GraphEditPart, and EdgeEditParts are orphans, i.e., they have no parent. Consequentially, I've had difficulties refreshing figures whenever Edges got added or deleted.

I've managed to make the update work when I added an Edge by doing an expensive iteration in the GraphAdapter (which is notified as a newly created Edge must be registered on the Graph (newEdge.setGraph(graph)):
if (notification.getOldValue() == null && notification.getNewValue() instanceof Edge) {
  for (Object ep : getChildren()) {
    if (ep instanceof NodeEditPart) { / There are in fact other EditParts as well
      Graph graph = (Graph) getModel();
      NodeEditPart nep = (NodeEditPart) ep;
      Node n = (Node) nep.getModel();
      if (graph.getOutEdges(n.getSId()).contains(notification.getNewValue()) || graph.getInEdges(n.getSId()).contains(notification.getNewValue()))
        nep.refresh();
}


[Note: If - by the way - you can think of any better way of doing this, feel free to hit me up with your solution!]

Problem


I am unable to reliably remove the Edge figure from the editor when deleting the Edge model object! Sometimes it works, sometimes it doesn't.

I guess the unreliability might have to do with the fact that (a) my real life model has three layers of abstraction, and (b) that different EMF Adapters don't always recognize changes in the same temporal order (?).

execute() from EdgeDeleteCommand simply calls edge.setGraph(null), which triggers EMF to clean up after itself (i.e., model elements that aren't connected to the graph are removed from the model).

How can I reliably remove Edges' figures when deleting the respective model object, when the respective EditPart is an orphan?
Re: Reliably remove Connection figures with orphan EditParts on deletion of model? [message #1017026 is a reply to message #1016992] Fri, 08 March 2013 12:02 Go to previous messageGo to next message
Stephan Druskat is currently offline Stephan Druskat
Messages: 52
Registered: October 2011
Location: Berlin, Germany
Member

Update: I'm on the case. Calling removeNotify() seems to get me quite far. Will post complete solution once I'm there.
Re: Reliably remove Connection figures with orphan EditParts on deletion of model? [message #1017974 is a reply to message #1017026] Tue, 12 March 2013 18:16 Go to previous message
Stephan Druskat is currently offline Stephan Druskat
Messages: 52
Registered: October 2011
Location: Berlin, Germany
Member

Found a solution: notify the source and target model objects programatically of the change, and let the Adapter attached to their EditParts handle the refresh...
Previous Topic:GEF 3.9 and Eclipse 4
Next Topic:Error in editor - how to fix?
Goto Forum:
  


Current Time: Thu Jul 31 13:48:15 EDT 2014

Powered by FUDForum. Page generated in 0.02356 seconds