GEF中SelectionToolEntry,MarqueeToolEntry选中连线

背景:

在默认的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为什么可以相应操作的源头  因为它优先提供了tracker
			if (handle != null) {                                       //当然这不是我们这次关注的重点
				setDragTracker(handle.getDragTracker());
				return true;
			}
		}
		updateTargetRequest();
		((SelectionRequest) getTargetRequest()).setLastButtonPressed(button);
		updateTargetUnderMouse();
		EditPart editpart = getTargetEditPart();
		if (editpart != null) {
			setDragTracker(editpart.getDragTracker(getTargetRequest()));  //根据不同的editpart获取不同的DragTracker
			lockTargetEditPart(editpart);
			return true;
		}
		return false;
	}

我大概统计了下:

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

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

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

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

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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值