首页 > 代码库 > 6.17 连接connection

6.17 连接connection

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 null30   } 31  32   @Override 33   protected Command getReconnectSourceCommand(ReconnectRequest request) { 34     // TODO Auto‐generated method stub 35     return null36   } 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