在开始之前,我们先讲一点预备的(我自己的理解,如果有错不能怪我)。
1. GEF中,一个连接线模型要成功创建,则这个模型必须有个源和目标。大家可以试一下连接一个源,再把目的随便在某个点一下,线是不会出来的(当然如果任务一个点都可以是目标的话,那就另论了)。
2. GEF中,一个连接线模型即使已经被附着到了源和目的上,也不一定会被显示出来。这就要提到AbstractGraphicalEditPart的两个方法:getModelSourceConnections()和getModelTargetConnections()。在前面讲getModelChildren()方法时提到过。这两个方法就是用来返回结点上的源连接线和目的连接线。所以其实我们真正要保证的是这两个方法返回的结果正确。
3. GEF中,一个模型对象要支持连接,它的EditPart必须实现一个接口:NodeEditPart。实现这个接口主要就是要实现它的四个方法用来确定连接线的锚点。一般来说简单的返回一个ChopboxAnchor对象就可以。当然也可以自己实现自定义的锚点算法。
首先、把结点对象定义好。
还是以我们的HelloWorldModel作为结点对象。按照上面所说进行动作。为了记录结点对象的源和目的线,首先我们加两上List和几个方法来存储和操作这些连接线。如下:
private List inputs = new ArrayList();
private List outputs = new ArrayList();
public List getInputs() {
return inputs;
}
public List getOutputs() {
return outputs;
}
public void addInput(AbstractConnectionModel model) {
if (!inputs.contains(model)) {
inputs.add(model);
}
}
public void addOut(AbstractConnectionModel model) {
if (!outputs.contains(model)) {
outputs.add(model);
}
}
public void removeInput(AbstractConnectionModel model) {
if (inputs.contains(model)) {
inputs.remove(model);
}
}
public void removeOut(AbstractConnectionModel model) {
if (outputs.contains(model)) {
outputs.remove(model);
}
}
这里因为要先用到,所以先假设所有的连接线的模型都继承自AbstractConnectionModel。
其次、修改结点的EditPart
让HelloWorldEditPart实现接口 :NodeEditPart。然后完成以下方法:
public ConnectionAnchor getSourceConnectionAnchor(
ConnectionEditPart connection) {
return new ChopboxAnchor(getFigure());
}
public ConnectionAnchor getSourceConnectionAnchor(Request request) {
return new ChopboxAnchor(getFigure());
}
public ConnectionAnchor getTargetConnectionAnchor(
ConnectionEditPart connection) {
return new ChopboxAnchor(getFigure());
}
public ConnectionAnchor getTargetConnectionAnchor(Request request) {
return new ChopboxAnchor(getFigure());
}
@Override
protected List getModelSourceConnections() {
return ((HelloWorldModel)getModel()).getOutputs();
}
@Override
protected List getModelTargetConnections() {
return ((HelloWorldModel)getModel()).getInputs();
}
这样,我们的结点模型就修改完了。
一、添加连接线的MVC结构。
需要注意的是,在GEF里,连接线也被当作一个模型来对待,因此我们首先就是要创建:模型、视图和控制。
注意:在前面已经说过,这里的连接EditPart需要继承:AbstractConnectionEditPart。
1.创建模型
按照刚才的说法,我们的连接线要继续自AbstractConnectionModel。之所以这样,是因为连接线的类型可能有多种,比如说带箭头的、不带箭头的;有路由点的、没有路由点的。但我们假设有一些是相通的:每个连接线只能有一个源、一个目的。所以我们的AbstractConnectionModel,可以实现如下:
public abstract class AbstractConnectionModel {
private HelloWorldModel src;
private HelloWorldModel target;
public HelloWorldModel getSrc() {
return src;
}
public void setSrc(HelloWorldModel src) {
this.src = src;
}
public HelloWorldModel getTarget() {
return target;
}
public void setTarget(HelloWorldModel target) {
this.target = target;
}
public void attachSource(){
if(!src.getOutputs().contains(this)){
src.addOut(this);
}
}
public void attachTarget(){
if(!target.getInputs().contains(this)){
target.addInput(this);
}
}
public void deattachSource(){
if(src.getOutputs().contains(this)){
src.removeOut(this);
}
}
public void deattachTarget(){
if(target.getInputs().contains(this)){
target.removeInput(this);
}
}
}
我们再写一个类:PlainConnectionModel继承这个类。什么都不用写。这就表示一个普通的连接线。
2。创建EditPart
我们创建一个PlainConnectionEditPart类,按照上面说的,这个类要继承:AbstractConnectionEditPart。内容暂时可以为空。
3。创建视图
视图可以先不管,因为连接线会有一个默认的视图。
4。关联MVC
在EditPartFactory里追加它们的关联:
if(model instanceof PlainConnectionModel){
PlainConnectionEditPart editPart = new PlainConnectionEditPart();
editPart.setModel(model);
return editPart;
}
我们先试一下效果。
修改Editor的initializeGraphicalViewer()方法。追加一个连接对象,如下:
@Override
protected void initializeGraphicalViewer() {
HelloWorldModel model1 = new HelloWorldModel();
model1.setConstraints(new Rectangle(10,0,100,20));
HelloWorldModel model2 = new HelloWorldModel();
model2.setConstraints(new Rectangle(100,50,100,20));
HelloWorldModel model3 = new HelloWorldModel();
model3.setConstraints(new Rectangle(50,100,100,20));
PlainConnectionModel connection = new PlainConnectionModel();
connection.setSrc(model1);
connection.setTarget(model2);
connection.attachSource();
connection.attachTarget();
DiagramRootContent content = new DiagramRootContent();
content.addChild(model1);
content.addChild(model2);
content.addChild(model3);
getGraphicalViewer().setContents(content);
}
运行效果如下:
图一
连接线已经被加上了。