假设以下简化的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
)摘录(还显示Edges
是Node
是来源还是目标的<{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
结构,其中NodeEditPart
是GraphEditPart
的子项,而 EdgeEditPart
是孤儿,即他们没有parent
。因此,每当添加或删除Edge
时,我都难以刷新数字。
通过在Edge
中执行昂贵的迭代(我以新创建的{{通知),添加 GraphAdapter
时,我设法使更新正常工作1}}必须在Edge
(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();
}
模型对象时,我无法从编辑器中可靠地删除Edge
数字!有时候它会起作用,有时却不起作用。
我认为不可靠性可能与(a)我的真实生活模型有三层抽象这一事实有关,而(b)则表示不同的EMF { {1}}并不总是识别相同时间顺序的变化(?)。
来自Edge
的 Adapter
只是调用execute()
,它会触发EMF自身清理(即,未从模型中删除的模型元素将从模型中删除)。
当相应的EdgeDeleteCommand
是孤儿时,如何在删除相应的模型对象时可靠地删除edge.setGraph(null)
s'数字?
答案 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
从未成为source
或target
的孩子。但是,附加到源 Adapter
的NodeEditPart
会注册此内容,并且可以做出如下反应。
@Override
public void notifyChanged(Notification notification) {
switch (notification.getEventType()) {
case Notification.REMOVE:
refresh();
break;
default:
break;
}
}
NodeEditPart.refresh()
方法会在途中调用getModelSourceConnections()
和getModelTargetConnections()
“,这将返回每个Edge
的列表,其中包含已删除的edge
不再了。