GEF中,选中一条连接线,默认的端点是两个小黑框,如下:
Figure 1
这个可用,不过终究是不太美观。这里介绍一下怎么修改这个选中的端点外观。修改后的效果如下:
Figure 2
首先有一点我们知道:通常要使得连线能够被选中,我们要在连接线对应的EditPart上安装以下Policy:
installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE, new ConnectionEndpointEditPolicy());
所以,我们知道,要想修改连线端点,我们需要从ConnectionEndpointEditPolicy下手。
ConnectionEndpointEditPolicy里有一个方法:createSelectionHandles()。这个方法就是提供端点选择的方法。其实我们在选中某个结点的时候,结点周围出现在带8个点的边框也是某个Policy提供的一些SelectionHandles。
所以下面我们的任务就是继承ConnectionEndpointEditPolicy,例如我们新写一个类:HomunculeConnectionEndpointPolicy,重写createSelectionHandles()方法。
我们看一下源码:
protected List createSelectionHandles() { List list = new ArrayList(); list.add(new ConnectionEndHandle((ConnectionEditPart)getHost())); list.add(new ConnectionStartHandle((ConnectionEditPart)getHost())); return list; }
可以看到,为了修改端点的显示,我们需要提供自己的ConnectionEndHandle和ConnectionStartHandle。最简单的就是分别写两个继承这两个类的类。然后重写paintFigure(Graphics)方法。
不过,有点可惜的是:ConnectionEndHandle和ConnectionStartHandle都是final的,所以没法继承。所以我们需要转而继承他们的父类了。还好,这个很简单,最后的结果如下:
HomunculeConnectionEndpointPolicy类:
public class HomunculeConnectionEndpointPolicy extends ConnectionEndpointEditPolicy { @Override protected List<ConnectionHandle> createSelectionHandles() { List<ConnectionHandle> list = new ArrayList<ConnectionHandle>(); list.add(new HomunculeConnectionEndHandle((ConnectionEditPart) getHost())); list.add(new HomunculeConnectionStartHandle((ConnectionEditPart) getHost())); return list; } }
HomunculeConnectionStartHandle类:
public class HomunculeConnectionStartHandle extends ConnectionHandle{ public HomunculeConnectionStartHandle(ConnectionEditPart host) { setOwner(host); setLocator(new ConnectionLocator(getConnection(), ConnectionLocator.SOURCE)); } /** * Creates and returns a new {@link ConnectionEndpointTracker}. * @return the new ConnectionEndpointTracker */ protected DragTracker createDragTracker() { if (isFixed()) return null; ConnectionEndpointTracker tracker; tracker = new ConnectionEndpointTracker((ConnectionEditPart)getOwner()); tracker.setCommandName(RequestConstants.REQ_RECONNECT_SOURCE); tracker.setDefaultCursor(getCursor()); return tracker; } @Override public void paintFigure(Graphics g) { Rectangle r = getBounds(); r.shrink(1, 1); try { g.setBackgroundColor(ColorConstants.green); g.fillOval(r); g.setForegroundColor(ColorConstants.darkBlue); g.drawOval(r); } finally { // We don't really own rect 'r', so fix it. r.expand(1, 1); } } }
HomunculeConnectionEndHandle类:
public class HomunculeConnectionEndHandle extends ConnectionHandle { public HomunculeConnectionEndHandle(ConnectionEditPart host) { setOwner(host); setLocator(new ConnectionLocator(getConnection(), ConnectionLocator.TARGET)); } /** * Creates and returns a new {@link ConnectionEndpointTracker}. * * @return the new ConnectionEndpointTracker */ protected DragTracker createDragTracker() { if (isFixed()) return null; ConnectionEndpointTracker tracker; tracker = new ConnectionEndpointTracker((ConnectionEditPart) getOwner()); tracker.setCommandName(RequestConstants.REQ_RECONNECT_TARGET); tracker.setDefaultCursor(getCursor()); return tracker; } @Override public void paintFigure(Graphics g) { Rectangle r = getBounds(); r.shrink(1, 1); try { g.setBackgroundColor(ColorConstants.green); g.fillOval(r); g.setForegroundColor(ColorConstants.darkBlue); g.drawOval(r); } finally { // We don't really own rect 'r', so fix it. r.expand(1, 1); } } }
最后就可以得到我们想要的结果。
多说一句:createDragTracker() 方法是用来重定向连接的!