如何在删除相应的模型对象时可靠地删除其EditPart为孤儿的连接图?

时间:2013-03-08 13:52:18

标签: model refresh listener eclipse-emf eclipse-gef

假设以下简化的EMF模型结构:

   Graph
   /   \
Node   Edge

在我的GEF编辑器中,EditPart的组织结构如下。

GraphEditPart (图= FreeformLayer)摘录

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

NodeEditPart (图=扩展Figure)摘录(还显示EdgesNode是来源还是目标的<{1}}

@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
}

编辑类摘录(如果重要)

@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);
}

所有EditPart都有自己的适配器(扩展org.eclipse.emf.ecore.util.EContentAdapter或实施org.eclipse.emf.common.notify.Adapter)。

这导致EditPart结构,其中NodeEditPartGraphEditPart的子项,而 EdgeEditPart是孤儿,即他们没有parent。因此,每当添加或删除Edge时,我都难以刷新数字。

通过在Edge中执行昂贵的迭代(我以新创建的{{通知),添加 GraphAdapter时,我设法使更新正常工作1}}必须在EdgeGraph)注册:

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(); } 模型对象时,我无法从编辑器中可靠地删除Edge数字!有时候它会起作用,有时却不起作用。

我认为不可靠性可能与(a)我的真实生活模型有三层抽象这一事实有关,而(b)则表示不同的EMF { {1}}并不总是识别相同时间顺序的变化(?)。

来自Edge

Adapter只是调用execute(),它会触发EMF自身清理(即,未从模型中删除的模型元素将从模型中删除)。

当相应的EdgeDeleteCommand是孤儿时,如何在删除相应的模型对象时可靠地删除edge.setGraph(null) s'数字?

1 个答案:

答案 0 :(得分:1)

只需让源模型对象和目标模型对象知道有关它们的内容已发生变化,并让其Adapter处理刷新。假设使用以下 EdgeDeleteCommand execute()方法。

@Override
public void execute() {
  graph = edge.getGraph();
  source = edge.getSource();
  target = edge.getTarget();

  edge.setGraph(null);
  source.eNotify(new NotificationImpl(Notification.REMOVE, edge, null));
  target.eNotify(new NotificationImpl(Notification.REMOVE, edge, null));
}

最后两行代码通知源和目标模型元素已从其中删除了对象edge。这实际上是通知消息,因为edge从未成为sourcetarget的孩子。但是,附加到源 Adapter NodeEditPart会注册此内容,并且可以做出如下反应。

@Override
public void notifyChanged(Notification notification) {
  switch (notification.getEventType()) {
  case Notification.REMOVE:
    refresh();
    break;

  default:
    break;
  }
}

NodeEditPart.refresh()方法会在途中调用getModelSourceConnections()getModelTargetConnections()“,这将返回每个Edge的列表,其中包含已删除的edge 不再了。