> 文档中心 > Common Navigator Framework 实践(二)菜单扩展

Common Navigator Framework 实践(二)菜单扩展

本文紧接
Eclipse插件(RCP)初始化资源文件和Common Navigator Framework 实践(一)自定义导航 介绍导航栏右键菜单扩展。

目标

在这里插入图片描述
如上图,当我们在导航资源右键时会出现很多菜单,这么多菜单在我们自己的RCP应用中不是必须的,或者是冗余的。那么我们如何去掉这些多余的菜单,自定义自己的菜单呢?

本文将介绍如何去掉那些冗余的右键菜单,并定义自己需要的右击菜单。效果见文末效果展示

分析

首先我们的分析这些菜单是从哪里定义的?
CNF提供的扩展点org.eclipse.ui.navigator.viewer有这些菜单的扩展方法,他们被定义为popupMenu

Eclipse ProjectExplorer 的实现如下:

<extension  point="org.eclipse.ui.navigator.viewer"><viewer      helpContext="org.eclipse.ui.project_explorer_context"      viewerId="org.eclipse.ui.navigator.ProjectExplorer">   <popupMenu  allowsPlatformContributions="true"  id="org.eclipse.ui.navigator.ProjectExplorer#PopupMenu">      <insertionPoint name="group.new"/>      <insertionPoint     name="group.open"     separator="true"/>      <insertionPoint name="group.openWith"/>      <insertionPoint name="group.edit"     separator="true"/>      <insertionPoint name="group.reorganize" />      <insertionPoint     name="group.port"     separator="true"/>      <insertionPoint     name="group.build"     separator="true"/>      <insertionPoint     name="group.generate"     separator="true"/>      <insertionPoint     name="group.search"     separator="true"/>      <insertionPoint     name="additions"     separator="true"/>      <insertionPoint     name="group.properties"     separator="true"/>   </popupMenu>      <!-- 其他信息省略 -->   </extension>

popupMenu 仅仅是定义了右击菜单可能出现的组或展示模板,它的内容是在各种Action、ActionGroup 或 ActionProvider(推荐)中实现的,它们需要在
扩展点org.eclipse.ui.navigator.viewer下的viewerActionBinding绑定。

实现

经过分析,需要两步实现自定义扩展菜单。

一、去除所有非自定义菜单

定义 popupMenu 扩展点且引用自定义导航内容,修改后的org.eclipse.ui.navigator.viewer 扩展点如下:

   <extension  point="org.eclipse.ui.navigator.viewer">      <viewer viewerId="com.xzbd.views.MainNavigator">      <popupMenu  allowsPlatformContributions="false"  id="com.xzbd.views.MainNavigator#PopupMenu"> </popupMenu>      </viewer>      <viewerContentBinding viewerId="com.xzbd.views.MainNavigator">  <includes><contentExtension pattern="com.xzbd.epx.MainNavigatorContent" /></includes>      </viewerContentBinding></extension>

修改扩展点 org.eclipse.ui.navigator.navigatorContent注意 triggerPoints 必须配置,不然启动时会报错

   <extension  point="org.eclipse.ui.navigator.navigatorContent">      <navigatorContent     activeByDefault="true"     id="com.xzbd.epx.MainNavigatorContent"     name="mainNavigatorContent"     labelProvider="com.xzbd.navigator.provider.MainLabelProvider"     contentProvider="com.xzbd.navigator.provider.MainContentProvider"     priority="normal">     <triggerPoints>     <or>  <instanceof value="org.eclipse.core.resources.IWorkspaceRoot" /> <instanceof value="org.eclipse.core.resources.IProject" /> <instanceof value="org.eclipse.core.resources.IResource" /> <instanceof value="org.eclipse.core.resources.IFolder" /><instanceof value="org.eclipse.core.resources.IFile" />     </or>  </triggerPoints>  <possibleChildren>     <instanceof    value="org.eclipse.core.resources.IProject">     </instanceof>  </possibleChildren>      </navigatorContent>   </extension>

此时启动项目,在导航中右击,将不会显示任何菜单。也就是说现在已经将所有不是我们设置的菜单去掉了。

二、添加自定义菜单、菜单组

  • popupMenu中添加菜单组 group.menu01group.menu02
      <popupMenu  allowsPlatformContributions="false"  id="com.xzbd.views.MainNavigator#PopupMenu">      <insertionPoint     name="group.menu01" separator="true">      </insertionPoint><insertionPoint     name="group.menu02" separator="true">      </insertionPoint></popupMenu>
  • 定义ActionProvider
    在扩展点org.eclipse.ui.navigator.navigatorContent定义actionProvider
<actionProvider     class="com.xzbd.navigator.provider.MainNavigatorActionProvider"     id="com.xzbd.actions.navigator.MainActionProvider"><enablement>    <or>  <instanceof value="org.eclipse.core.resources.IWorkspaceRoot" /> <instanceof value="org.eclipse.core.resources.IProject" /> <instanceof value="org.eclipse.core.resources.IResource" /> <instanceof value="org.eclipse.core.resources.IFolder" /><instanceof value="org.eclipse.core.resources.IFile" />     </or>   </enablement>      </actionProvider>

实现类 MainNavigatorActionProvider须继承org.eclipse.ui.navigator.CommonActionProvider,其实现如下:

package com.xzbd.navigator.provider;import org.eclipse.jface.action.IMenuManager;import org.eclipse.jface.action.MenuManager;import org.eclipse.jface.action.Separator;import org.eclipse.ui.navigator.CommonActionProvider;import com.xzbd.actions.TestAction01;import com.xzbd.actions.TestAction02;import com.xzbd.actions.TestAction03;public class MainNavigatorActionProvider extends CommonActionProvider {@Overridepublic void fillContextMenu(IMenuManager menu) {// 将 TestAction01 添加在 组 group.menu01 之前menu.insertBefore("group.menu01",new TestAction01());// 拼接后面menu.add(new TestAction02());// 将 TestAction03 添加在 组 group.menu01 之前menu.insertAfter("group.menu01", new TestAction03());menu.add(new Separator());// menu.add(new TestAction01());menu.add(new TestAction01());menu.add(new TestAction01());menu.add(new Separator());// 二级菜单MenuManager menuManager = new MenuManager("二级菜单");menuManager.add(new TestAction01());menuManager.add(new TestAction02());menuManager.add(new TestAction03());menu.add(menuManager);}}
  • 给菜单绑定 ActionProvider
    在扩展点org.eclipse.ui.navigator.viewer中绑定Action
   <extension  point="org.eclipse.ui.navigator.viewer">      <viewer viewerId="com.xzbd.views.MainNavigator">      <popupMenu>            </popupMenu>      </viewer>     <viewerContentBinding>      </viewerContentBinding>    <viewerActionBinding viewerId="com.xzbd.views.MainNavigator">    <includes>    <actionExtension pattern="com.xzbd.actions.*" />  </includes>    </viewerActionBinding></extension>
  • 测试按钮代码

TestAction01

package com.xzbd.actions;import org.eclipse.jface.action.Action;import com.xzbd.utils.AppPrinter;public class TestAction01 extends Action {public static final String ID = "com.xzbd.actions.TestAction01";private static final String TEXT = "我是测试按钮-add";public TestAction01() {setText(TEXT);}@Overridepublic void run() {AppPrinter.println("你点击了popupMenu -> ".concat(TEXT));}}

TestAction02

package com.xzbd.actions;import org.eclipse.jface.action.Action;import com.xzbd.utils.AppPrinter;public class TestAction02 extends Action {public static final String ID = "com.xzbd.actions.TestAction02";private static final String TEXT = "我是测试按钮-in goup menu01";public TestAction02() {setText(TEXT);}@Overridepublic void run() {AppPrinter.println("你点击了popupMenu -> ".concat(TEXT));}}

TestAction03

package com.xzbd.actions;import org.eclipse.jface.action.Action;import com.xzbd.utils.AppPrinter;public class TestAction03 extends Action {public static final String ID = "com.xzbd.actions.TestAction03";private static final String TEXT = "我是测试按钮-in goup menu02";public TestAction03() {setText(TEXT);}@Overridepublic void run() {AppPrinter.println("你点击了popupMenu -> ".concat(TEXT));}}
  • 导航相关所有 plugin.xml 配置
       <extension  point="org.eclipse.ui.views">      <view     class="com.xzbd.navigator.MainNavigator"     id="com.xzbd.views.MainNavigator"     name="导航栏"     restorable="true">      </view>      <view     class="com.xzbd.views.MessageConsoleView"     id="com.xzbd.views.MessageConsoleView"     name="控制台"     restorable="true">      </view>     </extension>         <extension  point="org.eclipse.ui.navigator.viewer">      <viewer viewerId="com.xzbd.views.MainNavigator">      <popupMenu  allowsPlatformContributions="false"  id="com.xzbd.views.MainNavigator#PopupMenu">      <insertionPoint     name="group.menu01" separator="true">      </insertionPoint><insertionPoint     name="group.menu02" separator="true">      </insertionPoint></popupMenu>      </viewer>      <viewerContentBinding viewerId="com.xzbd.views.MainNavigator">  <includes><contentExtension pattern="com.xzbd.epx.MainNavigatorContent" /></includes>      </viewerContentBinding> <viewerActionBinding viewerId="com.xzbd.views.MainNavigator">    <includes>    <actionExtension pattern="com.xzbd.actions.*" />  </includes> </viewerActionBinding></extension>      <extension  point="org.eclipse.ui.navigator.navigatorContent">      <navigatorContent     activeByDefault="true"     id="com.xzbd.epx.MainNavigatorContent"     name="mainNavigatorContent"     labelProvider="com.xzbd.navigator.provider.MainLabelProvider"     contentProvider="com.xzbd.navigator.provider.MainContentProvider"     priority="normal">     <triggerPoints>     <or>  <instanceof value="org.eclipse.core.resources.IWorkspaceRoot" /> <instanceof value="org.eclipse.core.resources.IProject" /> <instanceof value="org.eclipse.core.resources.IResource" /> <instanceof value="org.eclipse.core.resources.IFolder" /><instanceof value="org.eclipse.core.resources.IFile" />     </or>  </triggerPoints>  <possibleChildren>     <instanceof    value="org.eclipse.core.resources.IProject">     </instanceof>  </possibleChildren>      </navigatorContent>      <actionProvider     class="com.xzbd.navigator.provider.MainNavigatorActionProvider"     id="com.xzbd.actions.navigator.MainActionProvider"><enablement>    <or>  <instanceof value="org.eclipse.core.resources.IWorkspaceRoot" /> <instanceof value="org.eclipse.core.resources.IProject" /> <instanceof value="org.eclipse.core.resources.IResource" /> <instanceof value="org.eclipse.core.resources.IFolder" /><instanceof value="org.eclipse.core.resources.IFile" />     </or>   </enablement>      </actionProvider>   </extension>

效果展示

运行程序,在导航资源上右击,效果如下
在这里插入图片描述

总结

至此,通过分析如何入手,并且实现了自定义导航右击菜单自定义设置,并且给出了二级菜单的实现方案。注意虽然我们在popupMenu中定义两个菜单组,但是并没有对这两个组做实现,感兴趣的读者可以阅读org.eclipse.ui.internal.navigator.resources.actions.EditActionProvider 的实现,该类是对ProjectExplorer中group.edit的实现。

系列文章

CNF系列汇总
Common Navigator Framework 实践(一)自定义导航
Common Navigator Framework 实践(二)菜单扩展
Common Navigator Framework 实践(三)文件拖拽控制
Common Navigator Framework 实践(四)文件过滤
Common Navigator Framework 实践(五)菜单及工具条定制

资料

  • Common Navigator Framwork 参考资料

项目地址

  • epx