如何让natTable表格支持自定义多个右键菜单
在nebula中,官方默认提供了一个构造natTable的builder类,并且提供了一个debugInfo的默认右键菜单,但是当我们通过官方提供的builder去创建natTable,并且要添加多个右键菜单的时候,显得就不太灵活了,需要自己动手改改了,直接上代码吧:
1、创建一个抽象的菜单类AbstractMenuConfiguration:
public abstract class AbstractMenuConfiguration implements IMenuItemProvider {
private final String NAT_EVENT_DATA_KEY = "natEventData"; //$NON-NLS-1$
@Override
public void addMenuItem(NatTable natTable, Menu popupMenu) {
MenuItem inspectLabelsMenuItem = new MenuItem(popupMenu, SWT.PUSH);
inspectLabelsMenuItem.setText(getMenuName());
inspectLabelsMenuItem.setEnabled(true);
inspectLabelsMenuItem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
processEvent(getNatEventData(e));
}
});
}
private NatEventData getNatEventData(SelectionEvent selectionEvent) {
Widget widget = selectionEvent.widget;
if (widget == null || !(widget instanceof MenuItem)) {
return null;
}
MenuItem menuItem = (MenuItem) widget;
Menu parentMenu = menuItem.getParent();
Object data = null;
while (parentMenu != null) {
if (parentMenu.getData(this.NAT_EVENT_DATA_KEY) == null) {
parentMenu = parentMenu.getParentMenu();
} else {
data = parentMenu.getData(this.NAT_EVENT_DATA_KEY);
break;
}
}
return data != null ? (NatEventData) data : null;
}
protected abstract void processEvent(NatEventData natEventData);
protected abstract String getMenuName();
}
2、创建一个自定义PopupMenu构建类CustomerPopupMenuBuilder:
public class CustomerPopupMenuBuilder {
/**
* The active NatTable instance the context menu should be added to. Needed
* in advance to be able to add custom menu items that need the NatTable
* instance.
*/
protected NatTable natTable;
/**
* The {@link Menu} that is created with this popup menu builder.
*/
protected Menu popupMenu;
/**
* The {@link MenuManager} that is used by this popup menu builder. Can be
* <code>null</code> if plain SWT menu mechanisms are used.
*/
protected MenuManager menuManager;
/**
* Collection of all registered visibility state checkers for configured
* id's.
*/
protected final MenuItemStateMap visibility = new MenuItemStateMap();
/**
* Collection of all registered enablement state checkers for configured
* id's.
*/
protected final MenuItemStateMap enablement = new MenuItemStateMap();
/**
* Creates {@link CustomerPopupMenuBuilder} that builds up a new
* {@link Menu} that is only configurable with this instance of
* {@link CustomerPopupMenuBuilder}. Uses a {@link MenuManager} internally
* to be able to configure visibility and enabled states.
*
* @param parent
* The active NatTable instance the context menu should be added
* to.
*/
public CustomerPopupMenuBuilder(NatTable parent) {
this(parent, new MenuManager());
}
/**
* Creates a {@link CustomerPopupMenuBuilder} that builds up a new
* {@link Menu} using the given {@link MenuManager}.
*
* @param parent
* The active NatTable instance the context menu should be added
* to.
* @param manager
* The {@link MenuManager} that should be used to create the
* {@link Menu}.
*/
public CustomerPopupMenuBuilder(NatTable parent, MenuManager manager) {
this.natTable = parent;
this.menuManager = manager;
this.popupMenu = manager.createContextMenu(this.natTable);
}
/**
* Creates a popup menu builder based on the given menu. Using this enables
* the possibility to use configured context menus from plugin.xml and
* adding NatTable commands programmatically.
* <p>
* As an example you might want to create a PopupMenuBuilder by using a
* configured menu with the id
* <i>org.eclipse.nebula.widgets.nattable.example.contextmenu</i>
* <p>
*
* <pre>
* ISelectionProvider isp =
* new RowSelectionProvider<?>(selectionLayer, bodyDataProvider, false);
* MenuManager menuManager = new MenuManager();
* menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
* getSite().registerContextMenu(
* "org.eclipse.nebula.widgets.nattable.example.contextmenu", menuManager, isp);
* PopupMenuBuilder popupMenu =
* new PopupMenuBuilder(menuManager.createContextMenu(natTable));
* </pre>
* <p>
* For usage with Eclipse 4 you can use the <code>EMenuService</code> to
* register the menu to a NatTable instance. Afterwards get the menu and
* remove it from the NatTable to avoid the SWT control menu. The generated
* menu carries a {@link MenuManager} in the {@link Menu#getData()} which
* will be used within this {@link CustomerPopupMenuBuilder}.
* </p>
*
* <pre>
* menuService.registerContextMenu(natTable, menuId);
* Menu swtMenu = natTable.getMenu();
* natTable.setMenu(null);
* </pre>
*
* @param natTable
* The active NatTable instance which might be needed for
* creation of menu items that need the NatTable instance to
* work.
* @param menu
* The registered context menu.
*/
public CustomerPopupMenuBuilder(NatTable natTable, Menu menu) {
this.natTable = natTable;
this.popupMenu = menu;
// if the menu is build up using a MenuManager, remember that for
// further use
if (menu.getData() != null && menu.getData() instanceof MenuManager) {
this.menuManager = (MenuManager) menu.getData();
}
}
/**
* Adds the menu item provided by the given {@link IMenuItemProvider} to the
* popup menu. You can use this to add your own item to the popup menu.
* <p>
* Items added by this method can not be identified by id, so adding visible
* or enabled state checkers is not possible for these providers.
* </p>
*
* @param menuItemProvider
* The {@link IMenuItemProvider} that provides the menu item that
* should be added to the popup menu.
* @return The current {@link CustomerPopupMenuBuilder} with the added item.
*/
public CustomerPopupMenuBuilder withMenuItemProvider(IMenuItemProvider menuItemProvider) {
if (this.menuManager == null) {
menuItemProvider.addMenuItem(this.natTable, this.popupMenu);
} else {
this.menuManager.add(new PopupContributionItem(menuItemProvider));
}
return this;
}
/**
* Adds the menu item provided by the given {@link IMenuItemProvider} to the
* popup menu. You can use this to add your own item to the popup menu.
* <p>
* As items added by this method can be identified via the given id it is
* possible to register visible or enabled state checkers for these
* providers.
* </p>
*
* @param id
* The id under which the given {@link IMenuItemProvider} should
* be identifiable.
* @param menuItemProvider
* The {@link IMenuItemProvider} that provides the menu item that
* should be added to the popup menu.
* @return The current {@link CustomerPopupMenuBuilder} with the added item.
*/
public CustomerPopupMenuBuilder withMenuItemProvider(String id, IMenuItemProvider menuItemProvider) {
if (this.menuManager == null) {
menuItemProvider.addMenuItem(this.natTable, this.popupMenu);
} else {
this.menuManager.add(new PopupContributionItem(id, menuItemProvider));
}
return this;
}
/**
* Adds the menu item(s) provided by the given {@link ContributionItem} to
* the popup menu. You can use this to add your own item to the popup menu.
* <p>
* This method is only working if the {@link CustomerPopupMenuBuilder} is
* using a {@link MenuManager}.
* </p>
* <p>
* Using this adds support for visibility and enabled states of menu items.
* </p>
*
* @param contributionItem
* The {@link ContributionItem} that is used to add a menu item
* to the menu.
* @return The current {@link CustomerPopupMenuBuilder} with the added item.
* @throws IllegalStateException
* if this {@link CustomerPopupMenuBuilder} does not use a
* {@link MenuManager}
*/
public CustomerPopupMenuBuilder withContributionItem(ContributionItem contributionItem) {
if (this.menuManager == null) {
throw new IllegalStateException("This PopupMenuBuilder is not created using a MenuManager, " //$NON-NLS-1$
+ "therefore ContributionItems can not be added"); //$NON-NLS-1$
} else {
this.menuManager.add(contributionItem);
}
return this;
}
public CustomerPopupMenuBuilder configureMenuItemProvider(String mid, IMenuItemProvider menuItemProvider) {
return withMenuItemProvider(
mid,
menuItemProvider);
}
/**
* Adds a separator to the popup menu with the given id.
*
* @param id
* The id to identify the separator. Necessary if there should be
* visibility constraints for specific separators.
* @return The {@link CustomerPopupMenuBuilder} with an added separator.
* @see MenuItemProviders#separatorMenuItemProvider()
*/
public CustomerPopupMenuBuilder withSeparator(String id) {
return withMenuItemProvider(id, MenuItemProviders.separatorMenuItemProvider());
}
/**
* Builds and returns the created {@link Menu}.
* <p>
* <b>Note:</b> Calling this method will also add a {@link DisposeListener}
* to the NatTable instance to ensure the created {@link Menu} is disposed
* when the NatTable itself gets disposed.
* </p>
*
* @return The {@link Menu} that is created by this builder.
*/
public Menu build() {
this.natTable.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (CustomerPopupMenuBuilder.this.popupMenu != null
&& !CustomerPopupMenuBuilder.this.popupMenu.isDisposed())
CustomerPopupMenuBuilder.this.popupMenu.dispose();
}
});
return this.popupMenu;
}
/**
* Associate a visibility {@link IMenuItemState} with the menu item
* identified by the given id.
* <p>
* The visibility state is handled by the internal {@link MenuManager}. If
* no {@link MenuManager} is used, this method will have not effect.
* </p>
* <p>
* For the item to be visible, all associated {@link IMenuItemState} must be
* active OR no {@link IMenuItemState} must be associated with the item.
* </p>
*
* @param id
* the registered {@link IMenuItemState} will affect the menu
* item identified by the given id.
* @param state
* the {@link IMenuItemState} to queried for the visibility state
* of the menu item with the given id.
* @return This {@link CustomerPopupMenuBuilder} with the visible state
* checker for the given id.
*/
public CustomerPopupMenuBuilder withVisibleState(String id, IMenuItemState state) {
this.visibility.addMenuItemState(id, state);
return this;
}
/**
* Associate a enabled {@link IMenuItemState} with the menu item identified
* by the given id.
* <p>
* The enabled state is handled by the internal {@link MenuManager}. If no
* {@link MenuManager} is used, this method will have not effect.
* </p>
* <p>
* For the item to be enabled, all associated {@link IMenuItemState} must be
* active OR no {@link IMenuItemState} must be associated with the item.
* </p>
*
* @param id
* the registered {@link IMenuItemState} will affect the menu
* item identified by the given id.
* @param state
* the {@link IMenuItemState} to queried for the enabled state of
* the menu item with the given id.
* @return This {@link CustomerPopupMenuBuilder} with the enabled state
* checker for the given id.
*/
public CustomerPopupMenuBuilder withEnabledState(String id, IMenuItemState state) {
this.enablement.addMenuItemState(id, state);
return this;
}
/**
* Wrapper class to build up a {@link ContributionItem} based on a given
* {@link IMenuItemProvider}. If an id is set it is possible to register
* state checkers for enabled and visible state.
*/
protected class PopupContributionItem extends ContributionItem {
private IMenuItemProvider provider;
public PopupContributionItem(IMenuItemProvider provider) {
this(null, provider);
}
public PopupContributionItem(String id, IMenuItemProvider provider) {
super(id);
this.provider = provider;
}
@Override
public void fill(Menu menu, int index) {
List<MenuItem> beforeItems = Arrays.asList(menu.getItems());
this.provider.addMenuItem(CustomerPopupMenuBuilder.this.natTable, menu);
MenuItem[] afterItems = menu.getItems();
for (MenuItem item : afterItems) {
if (!beforeItems.contains(item)) {
// isEnabled() seems to be not called by the framework on
// opening a menu therefore we set it ourself. For this we
// also need to ensure isDynamic() returns true for
// re-rendering.
item.setEnabled(isEnabled());
}
}
}
@Override
public boolean isDynamic() {
return (getId() != null);
}
@Override
public boolean isEnabled() {
if (getId() != null) {
Object eventData = CustomerPopupMenuBuilder.this.popupMenu.getData(MenuItemProviders.NAT_EVENT_DATA_KEY);
if (eventData != null && eventData instanceof NatEventData) {
return CustomerPopupMenuBuilder.this.enablement.isActive(getId(), (NatEventData) eventData);
}
}
return true;
}
@Override
public boolean isVisible() {
if (getId() != null) {
Object eventData = CustomerPopupMenuBuilder.this.popupMenu.getData(MenuItemProviders.NAT_EVENT_DATA_KEY);
if (eventData != null && eventData instanceof NatEventData) {
return CustomerPopupMenuBuilder.this.visibility.isActive(getId(), (NatEventData) eventData);
}
}
return true;
}
}
}
3、实现自定义多右键菜单配置CustomerPopupMenuConfiguration:
public class CustomerPopupMenuConfiguration extends AbstractUiBindingConfiguration {
private Menu menu;
private CustomerPopupMenuBuilder customerPopupMenuBuilder;
public CustomerPopupMenuConfiguration(NatTable natTable) {
this.customerPopupMenuBuilder = new CustomerPopupMenuBuilder(natTable);
}
public CustomerPopupMenuConfiguration configureMenuItemProvider(String mid, IMenuItemProvider menuItemProvider) {
this.customerPopupMenuBuilder.configureMenuItemProvider(mid, menuItemProvider);
return this;
}
public CustomerPopupMenuConfiguration build() {
this.menu = this.customerPopupMenuBuilder.build();
return this;
}
@Override
public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
uiBindingRegistry.registerMouseDownBinding(
new MouseEventMatcher(SWT.NONE, null, 3),
new PopupMenuAction(this.menu));
}
}
4、后面剩下的就是怎么使用自定义菜单了配置了:
public class Test{
public void configure(NatTable natTable){
......
natTable.addConfiguration(new CustomerPopupMenuConfiguration(natTable).configureMenuItemProvider("addRowMenuItem", new AbstractMenuConfi guration(){
@Override
protected String getMenuName() {
return "add";
}
@Override
protected void processEvent(NatEventData natEventData) {
//处理增加
}
}).configureMenuItemProvider("updateRowMenuItem", new AbstractMenuConfiguration(){
@Override
protected String getMenuName() {
return "update";
}
@Override
protected void processEvent(NatEventData natEventData) {
// 处理修改
}
}).configureMenuItemProvider("deleteRowMenuItem", new AbstractMenuConfiguration(){
@Override
protected String getMenuName() {
return "delete";
}
@Override
protected void processEvent(NatEventData natEventData) {
//处理删除
}
}).build());
.....
}
}
以上就实现了灵活自定义右键菜单。
如何让natTable表格支持自定义多个右键菜单的更多相关文章
- JW Player 6.7(网页视频播放器,可在手机中播放),自定义Logo和右键菜单链接,支持MP3、MP4、FLV等格式,支持通过HTML5、FLash播放
原版下载地址:http://www.jwplayer.com/ JW Player是世界上最流行的网页影音播放器,支持的视频格式主要有:MP4.FLV.F4V等格式,支持的音频格式主要有:MP3.AA ...
- SNF快速开发平台MVC-EasyUI3.9之-DataGrid表格控件如何增加右键菜单
如题,我们在项目开发当中会遇到需要,表格控件增加右键菜单的使用. 下面我们就以SNF框架增加右键菜单步骤如下: 1.在加载页面当中增加如下菜单定义 <div id="mm" ...
- 验证实现element-ui树形控件的自定义图标及右键菜单
许久不用,element-ui已经更新至2.4.1版本.直接进入今天的正题,前提是node.js的环境还有vue及elment-ui都已经安装.由于element-ui的官方文档中介绍比较粗略,试了许 ...
- JS简单实现自定义右键菜单
RT,一个简单的例子,仅仅讲述原理 <div id="menu" style="width: 0;height: 0;background: cadetblue;p ...
- vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单
今天分享的不是技术,今天给大家分享个插件,针对现有的vue右键菜单插件,大多数都是需要使用插件本身自定义的标签,很多地方不方便,可扩展性也很低,所以我决定写了一款自定义指令调用右键菜单(vuerigh ...
- html鼠标自定义右键菜单:css+js实现自定义html右键菜单
我们在网页中很多都有右键菜单的功能,一般点击右键显示的是浏览器默认的菜单选项,那么我们直接如何通过css+js实现html的右键菜单呢?这篇文章将讲解html鼠标自定义右键菜单的实现原理和实现代码. ...
- Android 使Volley完美支持自定义证书的Https
其实在最早的版本里,Volley甚至是不支持https协议的,只能跑http,当然你也可以自己修改他的源码让他支持,如今volley的代码经过一些改进以后, 已经可以完美支持https协议了,无论是在 ...
- 工作随笔——selenium支持post请求,支持自定义header
背景: 最近在写一个小程序,发现博主所在的地区访问该网站时有防ddos功能验证导致程序不能正常工作. 经过试验发现可以用国外代理ip解决这个问题,但是程序走代理访问延迟高且不稳定. 思路: selen ...
- NOPI实现导入导出泛型List,支持自定义列
概述 业务上需要自定义列的Excel的导入导出,在网上看了好多资料,很多都是有Bug而且都是支持Excel和DataTable的转换,所以自己总结了一下,应用.NET平台上的NPOI封装了支持自定义列 ...
随机推荐
- Android面试收集录13 Android虚拟机及编译过程
一.什么是Dalvik虚拟机 Dalvik是Google公司自己设计用于Android平台的Java虚拟机,它是Android平台的重要组成部分,支持dex格式(Dalvik Executable)的 ...
- pdfmake实现中文支持,解决中文乱码问题
引言:当初自己为了在项目中bootstrap-table中实现导出pdf,使用的pdfmake,但是pdfmake默认使用的不是中文字体,实现pdfmake使用中文字体主要就是编译新的vfs_font ...
- WPF的线程模型
原文:WPF的线程模型 WPF的线程模型 周银辉 谈到多线程,很多人对其可能都不太有好感,觉得麻烦与易出错.所以我们不排除有这样的情况:假设我对“多线程”.“异步”这些字眼潜意识 ...
- 斐波那契数列(递归)&求100以内的素数
Java 5 添加了 java.util.Scanner 类,这是一个用于扫描输入文本的新的实用程序.它是以 前的 StringTokenizer 和 Matcher 类之间的某种结合.由于任何数据都 ...
- LDAP操作的两种方案
最近由于项目需要研究了一下LDAP相关知识,感觉对没接触过的人来说还是有点坑的,所以记录下来给大家分享. 由于是第一次接触,就在网上搜了一些相关的文章,照着示例代码测试,却怎么也连不上LDAP服务器, ...
- 【Max Points on a Line 】cpp
题目: Given n points on a 2D plane, find the maximum number of points that lie on the same straight li ...
- day06_02 元组
1.0 元组 元组被称为只读列表,即数据可以被查询,但不能被修改,所以,列表的切片操作同样适用于元组.元素卸载小括号(())里,元素之间用逗号隔开. tup1 = () #空元组 tup2 = (20 ...
- (笔记) RealTimeRender[实时渲染] C2
@author: 白袍小道 @来源:RealTime Render @建议书籍:龙书.RealTimeR第四版.GPUGem和PRO (来源:暗影不解释) 引点 这一章关注的管线中的管道功能,而非实现 ...
- 计算机图形学 opengl版本 第三版------胡事民 第四章 图形学中的向量工具
计算机图形学 opengl版本 第三版------胡事民 第四章 图形学中的向量工具 一 基础 1:向量分析和变换 两个工具 可以设计出各种几何对象 点和向量基于坐标系定义 拇指指向z轴正 ...
- PAT——甲级1046S:shortest Distance
这道题,折磨了我一个多小时,前前后后写了三个算法. 1046 Shortest Distance (20 point(s)) The task is really simple: given N ex ...