2013-03-08 2 views
1

는 다음과 같은 단순화 된 EMF 모델 구조를 가정합니다.각각의 모델 객체 제거시 연결 피겨 (EditParts가 고아 인)를 안정적으로 제거하는 방법은 무엇입니까? 다음과 같이</p> 내 GEF 편집기에서 <pre><code>Graph / Node Edge </code></pre> <p>의 <code>EditPart</code>의가 구성되어 있습니다

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 
} 

편집기 c 아가씨 (이 중요한 경우) 발췌

@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을 구현)이있다.

NodeEditPart S는 GraphEditPart의 자식 EditPart 구조를 초래하고 EdgeEditPart들, 즉을 고아, 그들은 더 parent 없다. 결과적으로, 나는 Edge이 추가되거나 삭제 될 때마다 수치를 상쾌하게하는 데 어려움을 겪었습니다. 내가 )가 Graph (newEdge.setGraph(graph)에 등록해야합니다 새로 만든 Edge로 통지되는합니다 (GraphAdapter에 고가의 반복을 수행하여 Edge을 추가 할 때

나는 업데이트 작업을 관리했습니다 :

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)가 서로 다른 EMF Adapter의 항상 변화를 인식하지 않는다는 사실과해야 할 수도 있습니다 추측 같은 시간 순서 (?). EdgeDeleteCommand에서

execute() 단순히 자체 (즉, 그래프에 연결되어 있지 않은 모델 요소 모델에서 제거) 뒤처리 EMF를 트리거하는 edge.setGraph(null) 부른다.

EditPart이 고아 인 경우 해당 모델 개체를 삭제할 때 Edge '자를 어떻게 안전하게 제거 할 수 있습니까?

+0

이 메시지 (아주 오래된!)는 삭제가 아니지만 연결을 다시 연결하는 것과 비슷한 문제를 설명합니다. http://dev.eclipse.org/mhonarc/lists/gef-dev/msg00198.html. 나는 '가장자리'를 추가 할 때 동일한 해결책을 적용하고 있지만, 삭제에는 효과가 없습니다. –

+0

코드를 살펴볼 가능성이 있습니까? – vainolo

+0

@vainolo : 다음은 주요 클래스의 클리닝 된 (well ...) 및 typefied 붙여 넣기입니다 : http://pastebin.com/GgQUt0dJ. 감사! –

답변

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이 (가) source 또는 target의 하위 프로그램이 아닙니다. 그러나 소스 및 대상에 첨부 된 AdapterNodeEditPart을 등록하며 다음과 같이 대응할 수 있습니다.

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

    default: 
    break; 
    } 
} 

NodeEditPart.refresh() 방법은 더 이상 그들 삭제 edge하지으로, Edge의 각각의 목록을 반환하는, "그것의 방법에"getModelSourceConnections()getModelTargetConnections()를 호출합니다.