Reliably remove Connection figures with orphan EditParts on deletion of model? [message #1016992] |
Fri, 08 March 2013 14:06 |
|
Assume the following simplified EMF model structure:
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?
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03056 seconds