part1
1.首先创建模型
(1)先创建抽象类AbstractConnectionModel,管理通用信息,这时里面还什么都没有。
public class AbstractConnectionModel { }
(2)再创建具体的类LineConnectionModel,继承自AbstractConnectionModel。
public class LineConnectionModel extends AbstractConnectionModel { }
(3)再就要创建对应于上面模型的控制器了,继承自org.eclipse.gef.editparts.AbstractConnectionEditPart 。
public class LineConnectionEditPart extends AbstractConnectionEditPart { @Override protected void createEditPolicies() { // TODO Auto‐generated method stub } }
(4)下面就要把模型和它的控制器联系起来。
public class PartFactory implements EditPartFactory { private EditPart getPartForElement(Object modelElement) { if (modelElement instanceof ContentsModel) return new ContentsEditPart(); else if (modelElement instanceof HelloModel) 应该是节点模型。 return new HelloEditorPart(); else if(modelElement instanceof LineConnectionModel) return new LineConnectionEditPart(); throw new RuntimeException( ?Can?t create part for model element: ? + ((modelElement != null) ? modelElement.getClass().getName() : ?null?)); } }
2.修改节点模型HelloModel,使其管理连接的起点和终点的信息。
1 public class HelloModel extends AbstractModel { 2 *************** 3 //connection //////////////////////////////////// 4 public static final String P_SOURCE_CONNECTION=?_source_connection?; 5 public static final String P_TARGET_CONNECTION=?_target_connection?; 6 7 private List sourceConnection=new ArrayList(); 8 private List targetConnection=new ArrayList(); 9 ////////////////////////////////////////////////// 10 *************** 11 //connection //////////////////////////////////// 12 public void addSourceConnection(Object connx){ 13 sourceConnection.add(connx); 14 firePropertyChange(P_SOURCE_CONNECTION,null,null); 15 } 16 17 public void addTargetConnection(Object connx){ 18 targetConnection.add(connx); 19 firePropertyChange(P_TARGET_CONNECTION,null,null); 20 } 21 22 public List getModelSourceConnections(){ 23 return sourceConnection; 24 } 25 26 public List getModelTargetConnections(){ 27 return targetConnection; 28 } 29 public void removeSourceConnection(Object connx){ 30 sourceConnection.remove(connx); 31 firePropertyChange(P_SOURCE_CONNECTION,null,null); 32 } 33 34 public void removeTargetConnection(Object connx){ 35 targetConnection.remove(connx); 36 firePropertyChange(P_TARGET_CONNECTION,null,null); 37 } 38 }
3.修改HelloModel的控制器HelloEditorPart。
1 public class HelloEditorPart extends EditPartWithListener implements NodeEditPart{ 2 // Abstract methods from NodeEditPart 3 public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) { 4 return new ChopboxAnchor(getFigure()); 5 } 6 7 public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connection) { 8 return new ChopboxAnchor(getFigure()); 9 } 10 11 public ConnectionAnchor getSourceConnectionAnchor(Request request) { 12 return new ChopboxAnchor(getFigure()); 13 } 14 15 public ConnectionAnchor getTargetConnectionAnchor(Request request) { 16 return new ChopboxAnchor(getFigure()); 17 } 18 }
4.刷新。
1 public class HelloEditorPart extends EditPartWithListener implements NodeEditPart{ 2 3 ************************ 4 public void propertyChange(PropertyChangeEvent event) { 5 if (event.getPropertyName().equals(HelloModel.P_CONSTRAINT)) 6 refreshVisuals(); // A view is updated. 7 else if (event.getPropertyName().equals(HelloModel.P_TEXT)) { 8 // Since the text of the model was changed, the text displayed on a view is updated 9 Label label = (Label) getFigure(); 10 label.setText((String) event.getNewValue()); 11 } 12 else if (event.getPropertyName().equals(HelloModel.P_SOURCE_CONNECTION)) 13 refreshSourceConnections(); 14 else if (event.getPropertyName().equals(HelloModel.P_TARGET_CONNECTION)) 15 refreshTargetConnections(); 16 } 17 18 protected List getModelSourceConnections(){ 19 return ((HelloModel)getModel()).getModelSourceConnections(); 20 } 21 22 public List getModelTargetConnections(){ 23 return ((HelloModel)getModel()).getModelTargetConnections(); 24 } 25 }
part2
1.先在 Palette 上加上“连接”工具。
(1)在 icon 那个目录中添加一个图标文件,这里的文件名是 arrowConnection.gif。
(2)然后在辅助接口中添加这个图标。
package gef.tutorial.step.helper; public interface IImageKeys{ public static final String EDITORTITLE="icons/example.gif"; public static final String NEWHELLOMODEL="icons/newModel.gif"; public static final String NEWCONNECTION="icons/newConnection.gif"; public static final String ARROWCONNECTION="icons/arrowConnection.gif"; }
(3)在DiagramEditor中添加“连接”工具。
1 public class DiagramEditor extends GraphicalEditorWithPalette { 2 ************************************ 3 protected PaletteRoot getPaletteRoot() { 4 // The route of a palette 5 PaletteRoot root = new PaletteRoot(); 6 // The group which stores tools other than model creation 7 PaletteGroup toolGroup = new PaletteGroup(?工具?); 10 11 // Creation and an addition of a ?selection? tool 12 ToolEntry tool = new SelectionToolEntry(); 13 toolGroup.add(tool); 14 root.setDefaultEntry(tool); // The tool which becomes active by the default 15 16 // Creation and an addition of a ?enclosure frame? tool 17 tool = new MarqueeToolEntry(); 18 toolGroup.add(tool); 19 20 21 //add the draw tool drawer 22 // The group which stores the tool which creates a model 23 PaletteDrawer drawer = new PaletteDrawer(?画图?); 26 27 ImageDescriptor descriptor = AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, IImageKeys.NEWHELLOMODEL); 29 30 // Creation and an addition of a ?creation of model? tool 31 CreationToolEntry creationEntry = 32 new CreationToolEntry( 33 ?绘制HelloModel?, // The character string displayed on a palette 36 ?创建HelloModel模型?, 42 43 new SimpleFactory(HelloModel.class), // The factory which creates a model 44 descriptor, // The image of 16X16 displayed on a palette 45 descriptor);// The image of 24X24 displayed on a palette 46 drawer.add(creationEntry); 47 48 //add the connection tool drawer 49 // The group which stores the tool which creates a connection 50 PaletteDrawer connectionDrawer = new PaletteDrawer(?连接?); 53 54 ImageDescriptor newConnectionDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, IImageKeys.NEWCONNECTION); 56 //在这个抽屉里放入New Connection工具 57 ConnectionCreationToolEntry connxCreationEntry= 58 new ConnectionCreationToolentry("简单连接", “创建简单连接”,new SimpleFactory(LineConnectionModel.class), newConnectionDescriptor//在Palette上的16*16的图标,newConnectionDescriptor//在Palette上的24*24的图标); 59 connectionDrawer.add(connxCreationEntry); 60 root.add(toolGroup); 61 root.add(drawer); 62 root.add(connectionDrawer); 63 64 return toot; 65 } 66 ************************************************ 67 }
part3
1.在AbstractConnectionModel中添加公共方法和属性。
public abstract class AbstractConnectionModel { private HelloModel source, target; //this connection?s root is connected to source 链接的头端添加到source public void attachSource(){ if(!source.getModelSourceConnections().contains(this)) source.addSourceConnection(this); } //this connection?s tip is connected to source 链接的尾端添加到target public void attachTarget(){ if(!target.getModelTargetConnections().contains(this)) target.addTargetConnection(this); } //this connection?s root is removed from source public void detachSource(){ source.removeSourceConnection(this); } //this connection?s tip is removed from target public void detachTarget(){ target.removeTargetConnection(this); } public HelloModel getSource() { return source; } public void setSource(HelloModel model) { source = model; } public HelloModel getTarget() { return target; } public void setTarget(HelloModel model) { target = model; } }
2.实现连接
(1)创建连接命令
public class CreateConnectionCommand extends Command { private HelloModel source, target; //两个模型一个用于起点,一个用于终点 private AbstractConnectionModel connection; //连接的模型 //首先判断是否能执行连接 public boolean canExecute(){ //execution is impossible when source or target is null if(source==null||target==null) return false; // if source is equal to target, the execution is not possible if(source.equals(target)) return false; return true; } public void execute(){ //执行的时候分两步:连接起点和连接终点 connection.attachSource(); connection.attachTarget(); } public void setConnection(Object model) { connection = (AbstractConnectionModel) model; } public void setSource(Object model) { source = (HelloModel)model; connection.setSource(source); } public void setTarget(Object model) { target = (HelloModel)model; connection.setTarget(target); } //同样,撤销Undo的时候也要分两步:撤销起点和撤销终点 public void undo(){ connection.detachSource(); connection.detachTarget(); } }
(2)实现连接相关的policy
(A)getConnectionCreateCommand中生成一个创建连接的命令CreateConnectionCommand。
(B)然后把命令用setStartCommand保存在命令堆栈中。
(C)而 在getConnectionCompleteCommand中 用getStartCommand方法再把CreateConnectionCommand命令取出来,一旦寻找到了终点,这个连接就创建了。
1 public class CustomGraphicalNodeEditPolicy extends GraphicalNodeEditPolicy { 2 3 @Override 4 protected Command getConnectionCompleteCommand(CreateConnectionRequest request) { 5 //命令是从request中获得(C) 6 CreateConnectionCommand command=(CreateConnectionCommand)request.getStartCommand(); 7 // setup the target 8 command.setTarget(getHost().getModel()); 9 return command; 10 } 11 12 @Override 13 protected Command getConnectionCreateCommand(CreateConnectionRequest request) { 14 CreateConnectionCommand command=new CreateConnectionCommand();(A) 15 16 //setup the connection model 17 command.setConnection(request.getNewObject()); 18 //setup the source 19 command.setSource(getHost().getModel()); 20 //创建连接的命令被记录(B) 21 22 request.setStartCommand(command); 23 return command; 24 } 25 26 @Override 27 protected Command getReconnectTargetCommand(ReconnectRequest request) { 28 // TODO Auto‐generated method stub 29 return null; 30 } 31 32 @Override 33 protected Command getReconnectSourceCommand(ReconnectRequest request) { 34 // TODO Auto‐generated method stub 35 return null; 36 } 37 }
(4)安装实现连接相关的Policy,只需要在 HelloEditorPart 中把连接 Policy 安装上就好了。
1 public class HelloEditorPart extends EditPartWithListener implements NodeEditPart{ 2 ************************************* 3 protected void createEditPolicies() { 4 installEditPolicy(EditPolicy.COMPONENT_ROLE,new CustomComponentEditPolicy()); 5 installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE,new CustomDirectEditPolicy()); 6 installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE,new CustomGraphicalNodeEditPolicy()); 7 } 8 **************************************** 9 }
3.删除连接
一个模型可能作为起点 Source 或终点 Target。所以删除模型的时候就要检查所有把该模型作为起点或终点的连接,把他们统统删除。
1 public class DeleteCommand extends Command { 2 private ContentsModel contentsModel; 3 private HelloModel helloModel; 4 5 //‐‐‐‐‐‐‐‐‐‐‐‐‐ Connection List‐‐‐‐‐‐‐‐‐‐‐ 6 private List sourceConnections=new ArrayList(); 7 private List targetConnections=new ArrayList(); 8 //////////////////////////////////////////// 9 10 // Override 11 public void execute() { 12 //‐‐‐‐‐‐‐‐‐ delete the connection ‐‐‐‐‐‐‐‐‐‐‐‐‐ 13 //在删除一个模型对象前,搜索把这个模型对象作为起点和终点的所有连接 14 15 sourceConnections.addAll(helloModel.getModelSourceConnections()); 16 targetConnections.addAll(helloModel.getModelTargetConnections()); 17 //删除该模型对象对应的source 18 for(int i=0;i<sourceConnections.size();i++){ 19 AbstractConnectionModel model=(AbstractConnectionModel)sourceConnections.get(i); 20 model.detachSource(); 21 model.detachTarget(); 22 } 23 24 //删除该模型对象对应的target 25 for(int i=0;i<targetConnections.size();i++){ 26 AbstractConnectionModel model=(AbstractConnectionModel)targetConnections.get(i); 27 model.detachSource(); 28 model.detachTarget(); 29 } 30 //‐‐‐‐‐‐‐‐‐ delete the connection ‐‐‐‐‐‐‐‐‐‐‐‐‐ 31 32 // A model is deleted. 33 contentsModel.removeChild(helloModel); 34 } 35 public void setContentsModel(Object model) { 36 contentsModel = (ContentsModel) model; 37 } 38 39 public void setHelloModel(Object model) { 40 helloModel = (HelloModel) model; 41 } 42 43 // Override 44 public void undo() { 45 // undo 46 contentsModel.addChild(helloModel);??? 47 48 //‐‐‐‐‐‐‐‐‐ undo the connection ‐‐‐‐‐‐‐‐‐‐‐‐‐ 49 for(int i=0;i<sourceConnections.size();i++){ 50 AbstractConnectionModel model=(AbstractConnectionModel)sourceConnections.get(i); 51 model.attachSource(); 52 model.attachTarget(); 53 } 54 for(int i=0;i<targetConnections.size();i++){ 55 AbstractConnectionModel model=(AbstractConnectionModel)targetConnections.get(i); 56 model.attachSource(); 57 model.attachTarget(); 58 } 59 //清除纪录,这些记录用于恢复 60 61 sourceConnections.clear(); 62 targetConnections.clear(); 63 //‐‐‐‐‐‐‐‐‐ undo the connection ‐‐‐‐‐‐‐‐‐‐‐‐‐ 64 } 65 }
6.17 连接connection