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.menu01
、group.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