次の単純化された 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
) の抜粋 (どのaがソースまたはターゲットであるかを示す方法も示します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);
}
すべてEditPart
の には独自のアダプターがあります (拡張org.eclipse.emf.ecore.util.EContentAdapter
または実装org.eclipse.emf.common.notify.Adapter
)。
これにより、が の子であり、が孤児である、つまり を持たないEditPart
構造が得られます。その結果、が追加または削除されるたびに図を更新するのに苦労しました。NodeEditPart
GraphEditPart
EdgeEditPart
parent
Edge
でコストのかかる反復を実行してを追加したときに、更新を機能させることができました(これは、新しく作成された を( )に登録する必要があることが通知されます):Edge
GraphAdapter
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
を削除するときに、エディタから Figureを確実に削除できません。Edge
うまくいくこともあれば、うまくいかないこともあります。
信頼性が低いのは、(a)私の現実のモデルには 3 つの抽象化層があり、(b)異なる EMFAdapter
が常に同じ時間順序で変化を認識しない (?) という事実に関係している可能性があると思います。
execute()
from はEdgeDeleteCommand
単純に を呼び出しますedge.setGraph(null)
。これにより、EMF はそれ自体の後でクリーンアップを開始します (つまり、グラフに接続されていないモデル要素がモデルから削除されます)。
それぞれのモデル オブジェクトが孤立Edge
している場合、それぞれのモデル オブジェクトを削除するときに、どのように s の図を確実に削除できますか?EditPart