对SelectionEditPolicy策略的源码分析

为什么,选中某个EditPart的时候会出现8个点组成的手柄(Handle)?
在前面的博文中,已经提及,在为我们的EditPart安装LayoutEditPolicy策略时,LayoutEditPolicy会为它的所有孩子安装策略(decorateChildren),实际上是安装了PRIMARY_DRAG_ROLE策略,一般情况会是SelectionEditPolicy的子类。


我们先来看看SelectionEditPolicy的activate方法的源代码:
public void activate() {
 super.activate();
 addSelectionListener();
 setSelectedState(getHost().getSelected());
 setFocus(getHost().hasFocus());
}

我们注意到了addSelectionListener方法,好像是添加了选中监听器。

跟踪进去看看,
protected void addSelectionListener() {
 selectionListener = new EditPartListener.Stub() {
  public void selectedStateChanged(EditPart part) {
   setSelectedState(part.getSelected());//更新选中状态
   setFocus(part.hasFocus());
  }
 };
 getHost().addEditPartListener(selectionListener);//给EditPolicy的Host添加了EditPartListener监听器
}

接着看看setSelectedState方法代码。
protected void setSelectedState(int type) {
 if (state == type)
  return;
 state = type;
 if (type == EditPart.SELECTED_PRIMARY)
  showPrimarySelection();
 else if (type == EditPart.SELECTED)
  showSelection();
 else
  hideSelection();
}

showPrimarySelection内部就是调用了showSelection。

接着看showSelection的实现。showSelection是个抽象方法,先看看SelectionEditPolicy的子类SelectionHandlesEditPolicy是怎样实现的
protected void showSelection() {
 addSelectionHandles();
}
关键方法是addSelectionHandles:
protected void addSelectionHandles() {
 removeSelectionHandles();
 IFigure layer = getLayer(LayerConstants.HANDLE_LAYER);//获取Handle层
 handles = createSelectionHandles();//抽象方法
 for (int i = 0; i < handles.size(); i++)
  layer.add((IFigure)handles.get(i));//将handle加到Handle Layer中
}

 

createSelectionHandles是一个抽象方法,我们看看SelectionHandlesEditPolicy子类ResizableEditPolicy中是如何实现createSelectionHandles的。
//创建了8个Handle 
/**
 * @see org.eclipse.gef.editpolicies.SelectionHandlesEditPolicy#createSelectionHandles()
 * 创建选中EditPart时的Handle
 */
protected List createSelectionHandles() {
 List list = new ArrayList();
 
 if (directions == 0)
  NonResizableHandleKit.addHandles((GraphicalEditPart)getHost(), list);
 else if (directions != -1) {
  ResizableHandleKit.addMoveHandle((GraphicalEditPart)getHost(), list);
  if ((directions & PositionConstants.EAST) != 0)
   ResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.EAST);
  else
   NonResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.EAST);
  if ((directions & PositionConstants.SOUTH_EAST) == PositionConstants.SOUTH_EAST)
   ResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.SOUTH_EAST);
  else
   NonResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.SOUTH_EAST);
  if ((directions & PositionConstants.SOUTH) != 0)
   ResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.SOUTH);
  else
   NonResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.SOUTH);
  if ((directions & PositionConstants.SOUTH_WEST) == PositionConstants.SOUTH_WEST)
   ResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.SOUTH_WEST);
  else
   NonResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
      PositionConstants.SOUTH_WEST);
  if ((directions & PositionConstants.WEST) != 0)
   ResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.WEST);
  else
   NonResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
      PositionConstants.WEST);
  if ((directions & PositionConstants.NORTH_WEST) == PositionConstants.NORTH_WEST)
   ResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.NORTH_WEST);
  else
   NonResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.NORTH_WEST);
  if ((directions & PositionConstants.NORTH) != 0)
   ResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.NORTH);
  else
   NonResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.NORTH);
  if ((directions & PositionConstants.NORTH_EAST) == PositionConstants.NORTH_EAST)
   ResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
     PositionConstants.NORTH_EAST);
  else
   NonResizableHandleKit.addHandle((GraphicalEditPart)getHost(), list,
      PositionConstants.NORTH_EAST); 
 } else
  ResizableHandleKit.addHandles((GraphicalEditPart)getHost(), list);
  return list;
}


现在我们应该已经弄清楚了,我们选中某个EditPart时,显示8个Handle点的流程了,因为EditPart添加了SelectionListener,当选中状态发生改变时,都会显示8个Handle点(如果你安装的是ResizableEditPolicy)。

问题的关键是,EditPart的选中状态是怎么改变的呢?

我们接下来看看这个问题。

看看AbstractEditPart中的setSelected方法的内容。
public void setSelected(int value) {
 if (selected == value)
  return;
 selected = value;
 fireSelectionChanged();//选择EditPart并触发选择事件
}

fireSelectionChanged的代码如下:
/**
 * Notifies <code>EditPartListeners</code> that the
 * selection has changed.
 */
protected void fireSelectionChanged() {
 Iterator listeners = getEventListeners(EditPartListener.class);
 while (listeners.hasNext())
  ((EditPartListener)listeners.next()).
   selectedStateChanged(this);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值