在gef项目中连线一直扮演这个不可或缺的角色。碰巧前段时间有个机会好好的看了这个部分的内容。下面就把我的一点点认识和大家分享。
首先要在模型上支持,能够保存连接的信息。对于不同的项目有不同的要求。我们通过两个例子就可以看出这一点来。
1、http://www13.plala.or.jp/observe/GEF/示例中的GEF6.zip (下面称这个例子为HelloWold)
运行的结果入下图所示:
它的模型可以使用如下的类图来表示:
用来描述Connection的分别是LineConnectionModel和ArrowConnectionModel这两个类。这两个类的父类和图形模型(HellowModel)相关。
2、IBM红皮书中的GEF范例(下面称这个例子为workflow)
运行效果如下图:
他的模型可用下面的类图描述:
其实连接的模型应该很简单,他只要能保存他的两端的对象就好了。图形模型(如HelloWold中的HelloModel)能够保持与他相关连的连接(HelloWold中的LineConnectionModel或ArrowConnectionModel)。
看完了Model,我们下面就可以看看EditPart部分了。
要看EditPart当然是要看最关键的了。也就是和连接直接关联的EditPart了。分别察看了和连接相关的EditPart,发现他们都会实现一个叫org.eclipse.gef.NodeEditPart的接口。如下图所示:
在nodeEditPart中有四个方法需要实现。通过这个四个方法的名字就可以看出他们和Anchor2密切相关。下面就来看看这几个方法的具体功能:
ConnectionAnchor
getSourceConnectionAnchor(ConnectionEditPart connection);
当需要画连接的时候,通过这个方法获取连接的源锚点。不管这个锚点在什么位置,他取得以后直接就用它作为源点了。
ConnectionAnchor
getSourceConnectionAnchor(Request request);
当在准备创建连接的时候,通过Request来获取新连接的源锚点。
另外的两个就不再啰嗦了。是为了获得目标的锚点。
但是我们肯定看到了HelloWold和Workflow中的连接有点不一样。HelloWold中直接是图元上的,而workflow是通过连接基本图元上面的一个子图元而连接的。简单来说就是他们连接的anchor有点不一样,这样就会出现执行结果的不同。
下面来看看他们到底是怎么实现的。根据上面提到的。锚点的获取是通过getSourceConnectionAnchor和getTargetConnectionAnchor方法来获取的。我们只需要好好比对一下他们这几个方法的不同就可以了。
HelloWold中的getSourceConnectionAnchor
public
ConnectionAnchor getSourceConnectionAnchor(Request request) {
returnnew
ChopboxAnchor(getFigure());
}
这里就简单的创建一个
ChopboxAnchor
就好了。这个就可以直接连到该Figure上了。
在workflow中这个情况稍微有一点复杂了。先不说,还是看看他的
getSourceConnectionAnchor
是怎么实现的。
public
ConnectionAnchor getSourceConnectionAnchor(
ConnectionEditPart connection)
{
Connection edge = (Connection)
connection.getModel();
return
getNodeFigure().getConnectionAnchor(edge.getSource().getName());
}
/**
*returnsananchorgivenitsname
*
*@paramportNamenameoftheanchor
*@returntheanchorwiththename<code>portName</code>
*/
public
ConnectionAnchor getConnectionAnchor(String portName) {
return
(ConnectionAnchor)connectionAnchors.get(
portName );
}
protected
Hashtable connectionAnchors
= new
Hashtable(7);
/**
*Addaninputportanditsanchor
*
*@paramportName
*uniquenametorefertotheport
*/
publicvoid
addInput(String portName) {
InputPortFigure inputPort = new
InputPortFigure();
add(inputPort);
PortConnectionAnchor anchor = new
PortConnectionAnchor(inputPort);
getTargetConnectionAnchors().add(anchor);
connectionAnchors.put(portName,
anchor);
}
通过这几个方法可以看出它是在添加Input时候就创建好了一个和PortFigure
相关Anchor并把它保存起来。在要用的时候就把它取出来。这样就搞定了。
具体的可以参考这两个例子的代码。好了,打完收工。
参考文档
IBM
红皮书
1、荒野困兽(老脸归来)’blog
2、GEF
进阶,第一部分:
Anchor