[zt]工具栏(Action Bar)

FROM:http://www.blog.edu.cn/user1/19180/archives/2006/1406358.shtml

对于图形界面工具来说,工具栏是必不可少的支持。对于Eclipse插件而言,工具栏可以分为两种:主工具栏(全局)和视图工具栏。从实现的角度上,二者没有什么太大区别,只是在初始化的时候略有不同。

 

工具条上的每一个按钮实际上是一个Action,每个Action负责执行一些功能。Action分为普通的Action和RetargetAction两种,我们看到的工具栏上的按钮其实都是RetargetAction,他们负责提供按钮的图标、说明等等,而真正的功能则由另一个普通的Action负责实现。这就是说,在普通的Action和RetargetAction之间存在一个对应关系,当用户点中工具栏上的RetargetAction时,其对应的Action将被执行(我们称这个Action为RetargetAction的handler)。一般来说,只要二者的ID一样,那么这两个Action之间就能自动建立这种对应。实际上,存在一个函数为RetargetAction建立handler,但是默认情况下GEF帮我们做了,有关映射的问题,稍后再做讨论。

自定义一个Action

下面给出一个RetargetAction的例子:

  1. public class MappingRetargetAction extends RetargetAction {   
  2.     public MappingRetargetAction() {   
  3.         super(MappingAction.ID, "do Mapping");   
  4.         setToolTipText("Mapping abstract Model");   
  5.         setImageDescriptor(ModelConstance.ICON_MAPPING_A);   
  6.         setDisabledImageDescriptor(ModelConstance.ICON_MAPPING_D);   
  7.     }   
  8. }  

上面的代码一目了然,这里不再做过多的解释。接下来创建MappingAction,也就是RetargetAction的Handler。MappingAction的作用是为模型元素进行语义映射,因而,我们首先需要选中一个模型元素——重点是,MappingAction必须是SelectionAction的子类。

SelectionAction用于实现选中元素的操作,如果某一项功能需要选中一些元素后才能执行,那么你就可以使用SelectionAction。SelectionAction是WorkbenchPartAction的子类,WorkbenchPartAction的子类还包括CopyTemplateAction、EditorPartAction、PrintAction、StackAction,这看起来比较晕,不过幸运的是最常用的还是SelectionAction,或者你可以直接继承自WorkbenchPartAction甚至是Action来实现你的功能。

对于每个WorkbenchPartAction来说,最重要的方法是calculateEnabled和run,前者用于判断这个Action是否可以被激活,后者则执行这些操作,这一点对于SelectionAction也是一样的,如下面的示例:

  1. public class MappingAction extends SelectionAction {   
  2.     final static public String ID = "USER_DEFINE:Mapping";   
  3.     protected MappingDialog dlg = null;   
  4.     public MappingAction(IWorkbenchPart part) {   
  5.         super(part);   
  6.         this.setId(ID);   
  7.     }   
  8.     protected boolean calculateEnabled() {   
  9.         IStructuredSelection s = (IStructuredSelection)this.getSelection();     
  10.         if(s==null||s.size()!=1return false;   
  11.         if(s.getFirstElement() instanceof DiagramPart) return false;   
  12.         if(s.getFirstElement() instanceof TextObjectModelPart) return true;   
  13.         return false;   
  14.     }   
  15.     public void run() {   
  16.         IStructuredSelection s = (IStructuredSelection)this.getSelection();   
  17.         if(dlg==null) dlg  = new MappingDialog((Shell)null);   
  18.         if(dlg.open()!=Window.OK) {   
  19.             return;   
  20.         }   
  21.         MappingTextObjectCommand c = new MappingTextObjectCommand();   
  22.         c.path = dlg.path;   
  23.         c.model = (TextObjectModel)((TextObjectModelPart)s.getFirstElement()).getModel();   
  24.         this.execute(c);   
  25.     }   
  26. }  

有两点需要说明,首先在初始化的时候Action的ID一定和之前的RetargetAction一致;其次,原则上run方法里可以实现全部的功能,但是出于复用的角度,我们还是讲真正的逻辑封装在一个Command里。

安装Action

首先我们需要一个ActionBarContributor,它用于创建主工具栏。其中我们主要需要实现三个函数:buildActions、declareGlobalActionKeys、contributeToToolBar。buildActions通常用于创建新的Action,declareGlobalActionKeys则用于声明那些已经存在RetargetAction的Action,比如有些功能如DELETE、UNDO、REDO等等。

GEF 在ActionBarContributor里维护了retargetActions和globalActionKeys两个列表,其中后者是一个Retarget Actions的ID列表,addRetargetAction()方法会把一个Retarget Action同时加到二者中,对于已有的Retarget Actions,我们应该在declareGlobalActionKeys()方法里调用addGlobalActionKey()方法来声明,在一个编辑器被激活的时候,与globalActionKeys里的那些ID具有相同ID值的(具有实际功能的)Action将被联系到该ID对应的Retarget Action,只要保证二者的ID相同即可实现映射。[八进制]

示例如下:

  1. public class DiagramActionBarContributor extends ActionBarContributor {   
  2.     protected void buildActions() {   
  3.         addRetargetAction(new DeleteRetargetAction());   
  4.         addRetargetAction(new MappingRetargetAction());   
  5.         addRetargetAction(new MappingRelationshipRetargetAction());   
  6.     }   
  7.     protected void declareGlobalActionKeys() {   
  8.     }   
  9.     public void contributeToToolBar(IToolBarManager toolBarManager) {   
  10.         toolBarManager.add(getAction(ActionFactory.DELETE.getId()));   
  11.         toolBarManager.add(getAction(MappingAction.ID));   
  12.         toolBarManager.add(getAction(MappingRelationshipAction.ID));   
  13.     }   
  14. }  

ActionBarContributor 中只设置了RetargetAction,真正实现功能的Action则要在Editor中进行设置。重载Editor的createActions,安装真正Action,如下:

java 代码
  1. protected void createActions() {   
  2.     super.createActions();   
  3.     IAction a;   
  4.     a = new MappingAction(this);   
  5.     getActionRegistry().registerAction(a);   
  6.     getSelectionActions().add(a.getId());   
  7.     ...   
  8. }  

最后在plugin.xml中的Extensions选项页里选择你的Editor,并在右侧Extension Element Details里设置ContributorClass为ActionBarContributor,主工具栏就会出现我们自定义的那个Action了。

PS:八进制这篇写的真不错,推荐一下http://bjzhanghao.cnblogs.com/archive/2005/03/30/128704.html

java 代码

java 代码

java 代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值