接触GEF有一段时间了,跟着鬼子写的那个小教程,确实有很多收获。
在GEF中经常用到连接,包括连接的创建、连接的删除以及连接的重新定向等。
1、想要删除或者对连接重新定向,首先要选中连接。在GEF中,使用ConnectionEndpointEditPolicy的派生类来实现。创建一个CustomConnectionEndpointEditPolicy,它继承自ConnectionEndpointEditPolicy。然后将CustomConnectionEndpointEditPolicy安装到我们的连接所对应的EditPart中。本例中,为所有连接创建了一个CustomAbstractConnectionEditPart,在其中添加代码:
public class CustomAbstractConnectionEditPart extends
AbstractConnectionEditPart {
@Override
protected void createEditPolicies() {
installEditPolicy(EditPolicy.CONNECTION_ROLE,
new CustomConnectionEditPolicy());
installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,
new CustomConnectionEndpointEditPolicy());
}
}
2、在创建连接的时候,创建了一个CustomGraphicalNodeEditPolicy,它继承自GraphicalNodeEditPolicy。其中自动生成的getReconnectTargetCommand与getReconnectSourceCommand方法就是用来重新定向的。
3、我们创建一个命令ReconnectSourceConnectionCommand,用于拖动句柄重新定向连接的Source端:
public class ReconnectSourceConnectionCommand extends Command {
private AbstractConnectionModel connection;
private RectangleModel source;
private RectangleModel oldSource;
public ReconnectSourceConnectionCommand(Object object,
Object newSource) {
super();
this.connection = (AbstractConnectionModel) object;
this.source = (RectangleModel) newSource;
}
public void execute() {
oldSource = connection.getSource();
connection.detachSource();
connection.setSource(source);
connection.attachSource();
}
public void undo() {
source = connection.getSource();
connection.detachSource();
connection.setSource(oldSource);
connection.attachSource();
}
}
4、在getReconnectSourceCommand方法调用上面的Command:
protected Command getReconnectSourceCommand(ReconnectRequest request) {
ReconnectSourceConnectionCommand command = new ReconnectSourceConnectionCommand(
request.getConnectionEditPart().getModel(), getHost().getModel());
return command;
}
这样,就可以重新定向了。然而,运行时却发现了一个问题:上边的重新定向可以允许连接的Source与Target在同一个图形上:
为此,我在ReconnectSourceConnectionCommand中修改代码:
public void execute() {
if(source.equals(connection.getTarget()))return ;
oldSource = connection.getSource();
connection.detachSource();
connection.setSource(source);
connection.attachSource();
}
这样倒是不会出现上图的情形了,但是还会出现另一个问题:当拖动连接的Source到Target所在的图形时,鼠标形状是+号,给人一种可以执行的错觉。
我突然明白了,一般创建Command时都有一个canExecute()方法用来判断能否执行,原来,它还能控制鼠标的图形。在ReconnectSourceConnectionCommand中添加代码:
public boolean canExecute() {
if (source == null)
return false;
if (source.equals(connection.getTarget()))
return false;
return true;
}
这样,在执行就好了:
重定向Target与重定向Source类似。