問題
在GMF中,如果需要programmatically刪除節點或連線,在google中我們很容易搜索到《GMF中,刪除節點和連線的實現》一文(我並不確定這是原創作者的原始鏈接),很多人可能都使用這種實現。這是一種很好的實現,但有時候也有其缺點--除了需要刪除View和Edge外,還需要刪除model,在element對應於各種不同的model時,顯然需要寫大量if else來處理不同的model。
實現
我們可以有另一種實現,通過request和command來實現,以下代碼刪除某個節點上所有的連線
public void deleteConnections(ShapeNodeEditPart editpart) { CompoundCommand compoundCommand =new CompoundCommand("delete all connections"); List connections = editpart.getTargetConnections(); connections.addAll(editpart.getSourceConnections()); GroupRequest deleteReq = new GroupRequest(RequestConstants.REQ_DELETE); deleteReq.setEditParts(connections); for (int i = 0; i < connections.size(); i++) { EditPart object = (EditPart) connections.get(i); Command deleteCmd = object.getCommand(deleteReq); if (deleteCmd != null) compoundCommand.add(deleteCmd); } editpart.getDiagramEditDomain().getDiagramCommandStack().execute(compoundCommand); }
刪除多個節點
public void deleteNodes(List editparts) { CompoundCommand compoundCommand =new CompoundCommand("delete nodes"); GroupRequest deleteReq = new GroupRequest(RequestConstants.REQ_DELETE); deleteReq.setEditParts(editparts); for (int i = 0; i < editparts.size(); i++) { EditPart object = (EditPart) editparts.get(i); Command deleteCmd = object.getCommand(deleteReq); if (deleteCmd != null) compoundCommand.add(deleteCmd); } ((ShapeNodeEditPart)editparts.get(0)).getDiagramEditDomain().getDiagramCommandStack().execute(compoundCommand); }
這種方式的好處是,不必關心底層model的刪除,因為每個element對應的command中,GMF已經幫我們實現了,更加簡單,且符合開放-閉合原則。並且,undo和redo也已經實現。
參考
org.eclipse.gef.ui.actions.DeleteAction
Binhua Liu原創,寫於2013/8/25。