本文紧接
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 {
@Override
public 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>
<!-- 绑定 Action Provider -->
<viewerActionBinding viewerId="com.xzbd.views.MainNavigator">
<includes>
<!-- 绑定自定义 Action ,可以写action provider id 通配符,也可以写id全字符串 -->
<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);
}
@Override
public 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);
}
@Override
public 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);
}
@Override
public 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的实现。
跟深入的实现请移步Eclipse插件(RCP)CND自定义导航按需引用Eclipse已实现的功能菜单
系列文章
CNF系列汇总
Common Navigator Framework 实践(一)自定义导航
Common Navigator Framework 实践(二)菜单扩展
Common Navigator Framework 实践(三)文件拖拽控制
Common Navigator Framework 实践(四)文件过滤
Common Navigator Framework 实践(五)菜单及工具条定制