以鼠标进入EditPartViewer为例讲解GEF执行流程

鼠标进入EditPartViewer时,FigureCanvas会将MouseMove事件交给其监器处理,
而FigureCanvas的监听器为LightweightSystem内部的EventHandler。
eg:
/**@see MouseMoveListener#mouseMove(MouseEvent)*/
 public void mouseMove(MouseEvent e) {
  getEventDispatcher().dispatchMouseMoved(e);
 }
 
由代码可知:
是将给EventDispatcher进行转发处理(dispatchMouseMoved(e))。
在GEF中,EventDispatcher为org.eclipse.gef.ui.parts.DomainEventDispatcher,
我们继续去看dispatchMouseMove的代码,
public void dispatchMouseMoved(org.eclipse.swt.events.MouseEvent me) {
 if (!editorCaptured) {
  super.dispatchMouseMoved(me);
  if (draw2dBusy())
   return;
 }
 if (okToDispatch()) {
  if ((me.stateMask & InputEvent.ANY_BUTTON) != 0)
   domain.mouseDrag(me, viewer);
  else
   domain.mouseMove(me, viewer);
 }
}
从代码看是,交给Editdomain处理了。EditDomain一般是org.eclipse.gef.DefaultEditDomain
domain.mouseMove(me, viewer);
继续跟踪:
public void mouseMove(MouseEvent mouseEvent, EditPartViewer viewer) {
 Tool tool = getActiveTool();
 if (tool != null)
  tool.mouseMove(mouseEvent, viewer);
}
需要明白的是,在EditDomain中,始终都会有且仅有一个Active Tool。
这下又交给Tool处理了,此时,默认的Tool为SelectionTool,请接着看代码,
protected boolean handleMove() {
 if (stateTransition(STATE_ACCESSIBLE_DRAG, STATE_INITIAL))
  setDragTracker(null);
 if (isInState(STATE_INITIAL)) {
  updateTargetRequest();//更新Reqeust,生成Request实例
  updateTargetUnderMouse();
  showTargetFeedback();
  return true;
 } else if (isInState(STATE_TRAVERSE_HANDLE)) {
  EditPartViewer viewer = getCurrentViewer();
  if (viewer instanceof GraphicalViewer) {
   Handle handle = ((GraphicalViewer) viewer).findHandleAt(getLocation());
   if (handle != null) {
    setState(STATE_ACCESSIBLE_DRAG);
    setStartLocation(getLocation());
    setDragTracker(handle.getDragTracker());
    return true;
   } else {
    setState(STATE_INITIAL);
   }
  }
 }
 return false;
}

生成Request实例的方法为updateTargetRequest,代码为:
protected void updateTargetRequest() {
 SelectionRequest request = (SelectionRequest)getTargetRequest();
 request.setModifiers(getCurrentInput().getModifiers());
 request.setType(getCommandName());
 request.setLocation(getLocation());
 updateHoverRequest();
 }
 
 protected Request getTargetRequest() {
 if (targetRequest == null)
  setTargetRequest(createTargetRequest());
 return targetRequest;
}
 
 
//SelectionTool中创建Request的方法
 protected Request createTargetRequest() {
 SelectionRequest request = new SelectionRequest();
 request.setType(getCommandName());
 return request;
}


Tool一般有getCommand方法,
以ResizeTracker为例,
protected Command getCommand() {
 List editparts = getOperationSet();
 EditPart part;
 CompoundCommand command = new CompoundCommand();
 command.setDebugLabel("Resize Handle Tracker");//$NON-NLS-1$
 for (int i = 0; i < editparts.size(); i++) {
  part = (EditPart)editparts.get(i);
  command.add(part.getCommand(getSourceRequest()));//转发给了EditPart,向EditPart要Command
 }
 return command.unwrap();
}


且看AbstractEditPart是如何将收到的请求分发给EditPolicy的。
public Command getCommand(Request request) {
 Command command = null;
 EditPolicyIterator i = getEditPolicyIterator();

 while (i.hasNext()) {
  if (command != null)
   command = command.chain(i.next().
    getCommand(request));
  else
   command = i.next().
    getCommand(request);
 }
 return command;
}

 

Tool通过getCommand后,会执行command。查看AbstractTool中有如下代码:
protected void executeCommand(Command command) {
 getDomain().getCommandStack().removeCommandStackEventListener(commandStackListener);
 try {
  getDomain().getCommandStack()
   .execute(command);
 } finally {
  getDomain().getCommandStack().addCommandStackEventListener(commandStackListener);
 }
}

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值