GEF中SelectionToolEntry,MarqueeToolEntry选中连线

来源:互联网 发布:淘宝视频拍摄设备 编辑:程序博客网 时间:2024/05/17 04:30

背景:

在默认的gef中,这两个鼠标工具都是不默认选中连线的. 但是多选节点,进行复制粘贴等操作时,总希望连续也是跟随节点的操作. 选中连线是基础. 

其实很简单,但又涉及到一点gef机制的探索,所以就立文记录下.

解决:

MarqueeToolEntry

进入源码看下豁然开朗.它用常量给出了自己的选中状态.并保存到marqueeBehavior中.通过ToolEntry.getToolProperty()获取状态.   而且提供了setToolProperty()的方法.  所以无需求甚解就可以解决.

// 4.0 创建一个GEF提供的 "Marquee多选"工具并将其放到toolGroup中toolEntry = new MarqueeToolEntry(); //修改区域选择tool支持选中关联连线toolEntry.setToolProperty(MarqueeSelectionTool.PROPERTY_MARQUEE_BEHAVIOR,MarqueeSelectionTool.BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS);

然后用户用的多的是SelectionToolEntry,并且它同样也提供多选.  所以SelectionToolEntry也得同样支持,否则用户跟你没完.  当然实际上MarqueeToolEntry可以废除了.

SelectionToolEntry

进入源码大失所望, 仿照上面的代码试试 也是无效.   看来得 求甚解才能解了.

不迈关子直接上源码阅读结果.   以下是当前的理解,可能有偏差. 如果机会和能力 我会写一篇关于Tool(基类是abstractTool)的机制文章.

toolEntry只是为了创建工具箱 更重要的是ToolEntry的下面方法获取的Tool

public Tool createTool() {if (toolClass == null)return null;Tool tool;try {tool = (Tool) toolClass.newInstance();} catch (IllegalAccessException iae) {return null;} catch (InstantiationException ie) {return null;}tool.setProperties(getToolProperties());   //tool获取了toolEntry的属性 toolEntry只是桥接return tool;}

而tool真正负责相应操作  直接处理事件  

MarqueeSelectionTool功能相对简单所以直接处理

SelectionTool是selectionToolEntry对应的工具. 它的功能相对复杂.它是在相应mouseDown的事件.直接确定鼠标位置下面是handle还是EditPart 然后从handle(或editPart)获取Tracker. tracker用于响应处理. 所以SelectionTool 才支持 多选,选中线,选中节点等复杂功能.   上源码:

protected boolean handleButtonDown(int button) {if (!stateTransition(STATE_INITIAL, STATE_DRAG)) {resetHover();return true;}resetHover();EditPartViewer viewer = getCurrentViewer();Point p = getLocation();if (getDragTracker() != null)getDragTracker().deactivate();if (viewer instanceof GraphicalViewer) {Handle handle = ((GraphicalViewer) viewer).findHandleAt(p); //handle为什么可以相应操作的源头  因为它优先提供了trackerif (handle != null) {                                       //当然这不是我们这次关注的重点setDragTracker(handle.getDragTracker());return true;}}updateTargetRequest();((SelectionRequest) getTargetRequest()).setLastButtonPressed(button);updateTargetUnderMouse();EditPart editpart = getTargetEditPart();if (editpart != null) {setDragTracker(editpart.getDragTracker(getTargetRequest()));  //根据不同的editpart获取不同的DragTrackerlockTargetEditPart(editpart);return true;}return false;}

我大概统计了下:

选中对象操作Tracker背景(ContentEditPart) 多选MarqueeDragTracker(眼熟吧)节点(NodeEditPart)选中节点/拖动DragEditPartsTracker线(LineEditPart)选中线/拖动SelectEditPartTracker这可以很明显的解释为什么.一个SelectionTool可以根据选中对象的不同执行不同的响应了.

甚解了 回去解决原来的问题.  方法很简单.

找到ContentEditPart 然后修改getDragTracker方法  将MarqueeDragTracker设置成可以选中线

不同的环境代码可能不同这是我的代码:

@Overrideprotected void configureGraphicalViewer() {super.configureGraphicalViewer();viewer = getGraphicalViewer();viewer.setEditPartFactory(new PartFactory());ScalableFreeformRootEditPart rootEditPart = new ScalableFreeformRootEditPart(){@Overridepublic DragTracker getDragTracker(Request req) {MarqueeDragTracker dt=new MarqueeDragTracker();dt.setMarqueeBehavior(MarqueeSelectionTool.BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS);return dt;}};viewer.setRootEditPart(rootEditPart);


0 0