1

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

   Graph
   /   \
Node   Edge

在我的 GEF 编辑器中,EditParts 的组织方式如下。

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)摘录(还显示了如何Edges获取Node源或目标

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

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

这导致了一个EditPart结构,其中NodeEditParts 是 的孩子GraphEditPartEdgeEditParts 是孤儿,即它们没有parentEdge因此,每当添加或删除 s时,我都难以刷新数字。

当我通过在中进行昂贵的迭代添加一个时,我已经设法使更新工作(通知为新创建的必须在()上注册:EdgeGraphAdapterEdgeGraphnewEdge.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从编辑器中删除图形!Edge有时有效,有时无效。

我想不可靠性可能与以下事实有关:(a)我的现实生活模型具有三层抽象,以及(b)不同Adapter的 EMF 并不总是能识别相同时间顺序的变化(?)。

execute()fromEdgeDeleteCommand简单的调用edge.setGraph(null),这会触发 EMF 自行清理(即,未连接到图的模型元素从模型中删除)。

当相应的模型对象是孤儿时,如何Edge在删除相应的模型对象时可靠地删除 s 的数字?EditPart

4

1 回答 1

1

只需让源模型对象和目标模型对象知道它们的某些内容发生了变化,并让它们Adapter处理刷新。假设下面EdgeDeleteCommandexecute()方法。

@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它从来都不是sourceor的孩子target。但是,Adapter附加到源和目标的 sNodeEditPart会注册这一点,并且可以做出如下反应。

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

  default:
    break;
  }
}

NodeEditPart.refresh()方法将调用getModelSourceConnections()and getModelTargetConnections()“on its way”,这将返回Edge每个 s 的列表,其中已删除的edge 不再包含在其中。

于 2013-03-12T22:12:46.247 回答