例如,新建,打开,删除,剪切,粘帖等等,这些命令通常出现在窗口的菜单和工具栏上

但是,在不同的情况下可能执行不同的操作。

开发这些功能的时候,我们通常无法预料未来将出想哪些新的需求。

所以,这些动能应当随着当前的活动的某些部件的而改变。好的实现方式是把这些功能实现的职责交给对应的部件。

如下图:

 

新建的按钮在当前激活的视图为“项目”视图时,应当是新建项目,如果是在文档视图中时,就应当是新建文档,同样删除的按钮也是一样的。

接下来我记录了我的实现方法:

1. 在创建窗口菜单和工具栏的类ApplicationActionBarAdvisor中:

代码
    protected void makeActions(IWorkbenchWindow window) {

        
// 保存
        saveAction = ActionFactory.SAVE.create(window);
        register(saveAction);
        
// 保存全部
        saveAllAction = ActionFactory.SAVE_ALL.create(window);
        register(saveAllAction);
        
// 保存全部
        saveAsAction = ActionFactory.SAVE_AS.create(window);
        register(saveAsAction);
        
// 关闭
        closeAction = ActionFactory.CLOSE.create(window);
        register(closeAction);
        
// 关闭全部
        closeAllAction = ActionFactory.CLOSE_ALL.create(window);
        register(closeAllAction);
        
        reOpenList 
= ContributionItemFactory.REOPEN_EDITORS.create(window);

        
// 退出系统
        exitAction = ActionFactory.QUIT.create(window);
        register(exitAction);

        
// 编辑菜单
        redoAction = ActionFactory.REDO.create(window);
        register(redoAction);
        undoAction 
= ActionFactory.UNDO.create(window);
        register(undoAction);
        cutAction 
= ActionFactory.CUT.create(window);
        register(cutAction);
        copyAction 
= ActionFactory.COPY.create(window);
        register(copyAction);
        pasteAction 
= ActionFactory.PASTE.create(window);
        register(pasteAction);
        deleteAction 
= ActionFactory.DELETE.create(window);
        register(deleteAction);

        
// 窗口
        openNewWindowAction = ActionFactory.OPEN_NEW_WINDOW.create(window);
        register(openNewWindowAction);

        editActionSetAction 
= ActionFactory.EDIT_ACTION_SETS.create(window);
        register(editActionSetAction);

        savePerspectiveAction 
= ActionFactory.SAVE_PERSPECTIVE.create(window);
        register(savePerspectiveAction);

        closePerspectiveAction 
= ActionFactory.CLOSE_PERSPECTIVE.create(window);
        register(closePerspectiveAction);

        closeAllPerspectiveAction 
= ActionFactory.CLOSE_ALL_PERSPECTIVES
                .create(window);
        register(closePerspectiveAction);

        resetPerspectiveAction 
= ActionFactory.RESET_PERSPECTIVE.create(window);
        register(resetPerspectiveAction);

        preferenceAction 
= ActionFactory.PREFERENCES.create(window);
        register(preferenceAction);

        
// 关于
        helpContentAction = ActionFactory.HELP_CONTENTS.create(window);  
        register(helpContentAction);  
        helpSearchAction 
= ActionFactory.HELP_SEARCH.create(window);  
        register(helpSearchAction);  
        helpDynamicAction 
= ActionFactory.DYNAMIC_HELP.create(window);  
        register(helpDynamicAction);  
        aboutAction 
= ActionFactory.ABOUT.create(window);
        register(aboutAction);

    }

这里有很多种方式创建系统的菜单,我只写两种。上面的一种是用程序写,例如:saveAction = ActionFactory.SAVE.create(window);

然后,把这些Action加入到菜单中:

代码
    protected void fillMenuBar(IMenuManager menuBar) {
        MenuManager systemMenu 
= new MenuManager("开始(&S)", UIConstants.M_SYSTEM);
        MenuManager editMenu 
= new MenuManager("编辑(&E)", UIConstants.M_EDIT);
        MenuManager navigateMenu 
= new MenuManager("导航(&V)",
                UIConstants.M_NAVIGATOR);
        MenuManager searchMenu 
= new MenuManager("查询(&A)", UIConstants.M_SEARCH);
        MenuManager windowMenu 
= new MenuManager("窗口(&W)",
                IWorkbenchActionConstants.M_WINDOW);
        MenuManager helpMenu 
= new MenuManager("帮助(&H)",
                IWorkbenchActionConstants.M_HELP);

        menuBar.add(systemMenu);
        menuBar.add(editMenu);
        menuBar.add(navigateMenu);
        menuBar.add(searchMenu);
        menuBar.add(
new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
        menuBar.add(windowMenu);
        menuBar.add(helpMenu);

        systemMenu.add(
new GroupMarker("intellifmea"));
        systemMenu.add(
new Separator(UIConstants.MB_RELOADOBJECT));
        systemMenu.add(saveAction);
        systemMenu.add(saveAllAction);
        systemMenu.add(saveAsAction);
        
        systemMenu.add(
new Separator());
        systemMenu.add(closeAction);
        systemMenu.add(closeAllAction);
        systemMenu.add(
new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        systemMenu.add(reOpenList);
        systemMenu.add(
new Separator("blank"));
        systemMenu.add(exitAction);

        editMenu.add(undoAction);
        editMenu.add(redoAction);
        editMenu.add(
new Separator());
        editMenu.add(cutAction);
        editMenu.add(copyAction);
        editMenu.add(pasteAction);
        editMenu.add(deleteAction);

        editMenu.add(
new Separator(IWorkbenchActionConstants.MB_ADDITIONS));

        navigateMenu
                .add(
new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

        windowMenu.add(openNewWindowAction);
        windowMenu.add(
new Separator());
        windowMenu.add(editActionSetAction);
        windowMenu.add(savePerspectiveAction);
        windowMenu.add(resetPerspectiveAction);
        windowMenu.add(closePerspectiveAction);
        windowMenu.add(closeAllPerspectiveAction);
        windowMenu.add(
new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        windowMenu.add(preferenceAction);

        searchMenu.add(
new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        
        helpMenu.add(helpContentAction);
        helpMenu.add(helpSearchAction);
        helpMenu.add(helpDynamicAction);
        helpMenu.add(aboutAction);
    }

第二种方法是直接在Plugins.xml上扩展

代码
      <menuContribution
            locationURI
="menu:com.sg.hyperobject.ui.systemmenu?after=intellifmea">
         
<command
               commandId
="com.sg.intellifmea.commands.CreateProjectWiz"
               disabledIcon
="icons/newobject_dis.gif"
               icon
="icons/newobject.gif"
               label
="新建(&amp;N)..."
               style
="push"
               tooltip
="创建一个新项目">
         
</command>
         
<command
               commandId
="com.sg.intellifmea.commands.Open"
               icon
="icons/Open.gif"
               label
="打开(&amp;O)..."
               tooltip
="打开">
         
</command>
      
</menuContribution>

请注意locationURI="menu:com.sg.hyperobject.ui.systemmenu?after=intellifmea"指定了这个菜单应当出现的位置是在intellifmea之后的。intellifmea是什么呢?

请看上文中我们为systemMenu留出的扩展菜单的一个GroupMarker,(在fillMenuBar方法中 ) systemMenu.add(new GroupMarker("intellifmea"));

这样,pluins.xml中定义的菜单就加在了指定的位置了(这种扩展同样适用于扩展各种各样的工具栏和菜单,例如视图的菜单工具栏以及右键菜单)

2. 为菜单指定Command

代码
   <extension
         
point="org.eclipse.ui.commands">
      
<category
            
id="com.sg.intellifmea.project"
            name
="intellifmea project">
      
</category>
      
<command
            
categoryId="com.sg.intellifmea.project"
            id
="com.sg.intellifmea.commands.CreateProjectWiz"
            name
="CreateProjectWiz">
      
</command>
      
<command
            
categoryId="com.sg.intellifmea.project"
            id
="com.sg.intellifmea.commands.Open"
            name
="OpenProject">
      
</command>
      
<command
            
categoryId="com.sg.intellifmea.project"
            id
="com.sg.intellifmea.commands.ProjectProcess"
            name
="ProjectProcess">
      
</command>
      
<command
            
categoryId="com.sg.intellifmea.project"
            id
="com.sg.intellifmea.commands.ProjectPause"
            name
="ProjectPause">
      
</command>
      
<command
            
categoryId="com.sg.intellifmea.project"
            id
="com.sg.intellifmea.commands.ProjectFinish"
            name
="ProjectFinish">
      
</command>
      
<command
            
categoryId="com.sg.intellifmea.project"
            id
="com.sg.intellifmea.commands.ProjectCancel"
            name
="ProjectCancel">
      
</command>
      
<command
            
categoryId="com.sg.intellifmea.project"
            id
="com.sg.intellifmea.commands.ProjectViewerReload"
            name
="ProjectViewerReload">
      
</command>
      
<command
            
categoryId="com.sg.intellifmea.project"
            id
="com.sg.intellifmea.commands.SetCurrentProject"
            name
="SetCurrentProject">
      
</command>
      
<command
            
categoryId="com.sg.intellifmea.project"
            id
="com.sg.intellifmea.commands.CreateDocument"
            name
="CreateDocument">
      
</command>
   
</extension>

扩展org.eclipse.commands扩展点

3. 为command指定Handler

扩展 "org.eclipse.ui.handlers"

这里可以指定commands的调用时执行的方法,可以控制该command的是否可用。当然这里还涉及到一个系统性的知识。包括了表达式,选择等等,这里不详述。

代码
  <extension
         
point="org.eclipse.ui.handlers">
      
<handler
            
class="com.sg.intellifmea.commands.CreateProjectWiz"
            commandId
="com.sg.intellifmea.commands.CreateProjectWiz">
      
</handler>
      
<handler
            
class="com.sg.intellifmea.commands.Open"
            commandId
="com.sg.intellifmea.commands.Open">
         
<enabledWhen>
            
<count
                  
value="1">
            
</count>
         
</enabledWhen>
      
</handler>
      
<handler
            
class="com.sg.intellifmea.commands.ProjectProcess"
            commandId
="com.sg.intellifmea.commands.ProjectProcess">
         
<activeWhen>
            
<count
                  
value="1">
            
</count>
         
</activeWhen>
         
<enabledWhen>
            
<iterate
                  
ifEmpty="false">
               
<test
                     
args="进行"
                     property
="com.sg.intellifmea.tester.ProjectStatusChangeableTest">
               
</test>
            
</iterate></enabledWhen>
      
</handler>
      
<handler
            
class="com.sg.intellifmea.commands.ProjectPause"
            commandId
="com.sg.intellifmea.commands.ProjectPause">
         
<activeWhen>
            
<count
                  
value="1">
            
</count>
         
</activeWhen>
         
<enabledWhen>
            
<iterate
                  
ifEmpty="false">
               
<test
                     
args="暂停"
                     property
="com.sg.intellifmea.tester.ProjectStatusChangeableTest">
               
</test>
            
</iterate>
         
</enabledWhen>
      
</handler>
      
<handler
            
class="com.sg.intellifmea.commands.ProjectFinish"
            commandId
="com.sg.intellifmea.commands.ProjectFinish">
         
<activeWhen>
            
<count
                  
value="1">
            
</count>
         
</activeWhen>
         
<enabledWhen>
            
<iterate
                  
ifEmpty="false">
               
<test
                     
args="完成"
                     property
="com.sg.intellifmea.tester.ProjectStatusChangeableTest">
               
</test>
            
</iterate>
         
</enabledWhen>
      
</handler>
      
<handler
            
class="com.sg.intellifmea.commands.ProjectCancel"
            commandId
="com.sg.intellifmea.commands.ProjectCancel">
         
<activeWhen>
            
<count
                  
value="1">
            
</count>
         
</activeWhen>
         
<enabledWhen>
            
<iterate
                  
ifEmpty="false">
               
<test
                     
args="取消"
                     property
="com.sg.intellifmea.tester.ProjectStatusChangeableTest">
               
</test>
            
</iterate>
         
</enabledWhen>
      
</handler>
      
<handler
            
class="com.sg.intellifmea.commands.ProjectViewerReload"
            commandId
="com.sg.intellifmea.commands.ProjectViewerReload">
      
</handler>
      
<handler
            
class="com.sg.intellifmea.commands.SetCurrentProject"
            commandId
="com.sg.intellifmea.commands.SetCurrentProject">
         
<activeWhen>
            
<count
                  
value="1">
            
</count>
         
</activeWhen>
         
<enabledWhen>
            
<iterate
                  
ifEmpty="false">
               
<and>
                  
<test
                        
args="工作"
                        property
="com.sg.intellifmea.tester.ProjectStatusChangeableTest">
                  
</test>
                  
<not>
                     
<test
                           
property="com.sg.intellifmea.tester.IsWorkingProject">
                     
</test>
                  
</not>
               
</and>
            
</iterate>
         
</enabledWhen>
      
</handler>
      
<handler
            
class="com.sg.intellifmea.commands.CreateDocument"
            commandId
="com.sg.intellifmea.commands.CreateDocument">
         
<activeWhen>
            
<with
                  
variable="activePartId">
               
<equals
                     
value="com.sg.intellifmea.view.ProjectView">
               
</equals>
            
</with>
         
</activeWhen>
         
<enabledWhen>
            
<count
                  
value="1">
            
</count>
         
</enabledWhen>
      
</handler>
   
</extension>

4. 指定键盘的快捷键

扩展org.eclipse.ui.bindings设置快捷键,以下是例子

代码
  <extension
        
point="org.eclipse.ui.bindings">
     
<key
           
commandId="com.sg.hyperobject.commands.dataobject.OpenObject"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+O">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.dataobject.MakeWipDTO"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M2+F2">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.dataobject.DeleteDTO"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M2+DEL">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.dataobject.CopySelectionDTO"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+M2+T">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.search.FindInResult"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+F3">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.search.FindInResultNext"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="F3">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.tableediting.InsertItem"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+I">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.tableediting.AppendItem"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+A">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.tableediting.MoveUp"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+ARROW_UP">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.tableediting.MoveDown"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+ARROW_DOWN">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.tableediting.LinkItem"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+L">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.ui.HideAssistant"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+H">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.tableediting.CopyItem"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+M2+C">
     
</key>
     
<key
           
commandId="com.sg.hyperobject.commands.tableediting.PasteItem"
           contextId
="org.eclipse.ui.contexts.window"
           schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
           sequence
="M1+M2+P">
     
</key>
  
</extension>

到此为止,我们基于Plugins.xml实现了菜单。

5. 不同的部件中具有不同的功能的全局菜单和工具栏

我们只需要在该部件中加入以下代码,这个id的菜单功能就被替换了。

奇怪的是,似乎这个替换并不需要我们主动地在侦听激活或者非激活状态。也无需我们主动地clear

getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(), deleteAction);

我们在创建文档视图的方法中,加上上面的一句话,那么在文档视图中,点击删除按钮,deleteAction就被执行了

同样,我们在创建项目视图的方法中, 加上上面的一句话,那么在项目视图中,点击删除按钮,项目视图的deleteAction就被执行了,而不是执行的文档视图的删除方法。

 

 

 

 

 

posted on 2009-12-06 17:21  钟华  阅读(3105)  评论(0编辑  收藏  举报