在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&lt;?&gt;(selectionLayer, bodyDataProvider, false);
* MenuManager menuManager = new MenuManager();
* menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
* getSite().registerContextMenu(
* &quot;org.eclipse.nebula.widgets.nattable.example.contextmenu&quot;, 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表格支持自定义多个右键菜单的更多相关文章

  1. JW Player 6.7(网页视频播放器,可在手机中播放),自定义Logo和右键菜单链接,支持MP3、MP4、FLV等格式,支持通过HTML5、FLash播放

    原版下载地址:http://www.jwplayer.com/ JW Player是世界上最流行的网页影音播放器,支持的视频格式主要有:MP4.FLV.F4V等格式,支持的音频格式主要有:MP3.AA ...

  2. SNF快速开发平台MVC-EasyUI3.9之-DataGrid表格控件如何增加右键菜单

    如题,我们在项目开发当中会遇到需要,表格控件增加右键菜单的使用. 下面我们就以SNF框架增加右键菜单步骤如下: 1.在加载页面当中增加如下菜单定义 <div id="mm" ...

  3. 验证实现element-ui树形控件的自定义图标及右键菜单

    许久不用,element-ui已经更新至2.4.1版本.直接进入今天的正题,前提是node.js的环境还有vue及elment-ui都已经安装.由于element-ui的官方文档中介绍比较粗略,试了许 ...

  4. JS简单实现自定义右键菜单

    RT,一个简单的例子,仅仅讲述原理 <div id="menu" style="width: 0;height: 0;background: cadetblue;p ...

  5. vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单

    今天分享的不是技术,今天给大家分享个插件,针对现有的vue右键菜单插件,大多数都是需要使用插件本身自定义的标签,很多地方不方便,可扩展性也很低,所以我决定写了一款自定义指令调用右键菜单(vuerigh ...

  6. html鼠标自定义右键菜单:css+js实现自定义html右键菜单

    我们在网页中很多都有右键菜单的功能,一般点击右键显示的是浏览器默认的菜单选项,那么我们直接如何通过css+js实现html的右键菜单呢?这篇文章将讲解html鼠标自定义右键菜单的实现原理和实现代码. ...

  7. Android 使Volley完美支持自定义证书的Https

    其实在最早的版本里,Volley甚至是不支持https协议的,只能跑http,当然你也可以自己修改他的源码让他支持,如今volley的代码经过一些改进以后, 已经可以完美支持https协议了,无论是在 ...

  8. 工作随笔——selenium支持post请求,支持自定义header

    背景: 最近在写一个小程序,发现博主所在的地区访问该网站时有防ddos功能验证导致程序不能正常工作. 经过试验发现可以用国外代理ip解决这个问题,但是程序走代理访问延迟高且不稳定. 思路: selen ...

  9. NOPI实现导入导出泛型List,支持自定义列

    概述 业务上需要自定义列的Excel的导入导出,在网上看了好多资料,很多都是有Bug而且都是支持Excel和DataTable的转换,所以自己总结了一下,应用.NET平台上的NPOI封装了支持自定义列 ...

随机推荐

  1. [转] PHP在不同页面之间传值的三种常见方式

    转自: http://my.oschina.net/jiec/blog/196153 一. POST传值 post传值是用于html的<form>表单跳转的方法,很方便使用.例如: < ...

  2. 剑指Offer - 九度1515 - 打印1到最大的N位数

    剑指Offer - 九度1515 - 打印1到最大的N位数2013-11-30 01:11 题目描述: 给定一个数字N,打印从1到最大的N位数. 输入: 每个输入文件仅包含一组测试样例.对于每个测试案 ...

  3. CSS系列(6) CSS通配符详解

    通配符使用星号*表示,意思是“所有的”. 平时使用电脑,比如要搜索C盘里所有的网页,可以使用 *.html来搜索,.html是网页的后缀名,*代表了所有网页的名称: 也就是使用 * 加后缀名,就可以在 ...

  4. 【Divided Two】cpp

    题目: Divide two integers without using multiplication, division and mod operator. If it is overflow, ...

  5. Python爬虫教程

    Python爬虫(1):基本原理 Python爬虫(2):Requests的基本用法 Python爬虫(3):Requests的高级用法 Python爬虫(4):Beautiful Soup的常用方法 ...

  6. Metadata 的概念

    https://www.ibm.com/developerworks/cn/cloud/library/1509_liukg_openstackmeta/ http://mathslinux.org/ ...

  7. STL之queue&stack使用简介

       queue 队列也是一个线性存储表,与后进先出的堆栈不同,元素数据的插入在表的一端进行,在另一端删除,从而构成了一个先进先出(First In First Out) 表.插入一端称为队尾,删除一 ...

  8. ASP.NET 抓取网页内容

    (转)ASP.NET 抓取网页内容 ASP.NET 抓取网页内容-文字 ASP.NET 中抓取网页内容是非常方便的,而其中更是解决了 ASP 中困扰我们的编码问题. 需要三个类:WebRequest. ...

  9. try...catch 语句

    一般情况下,我们很少用到 try...catch 语句,但是有时候为了测试代码中的错误,也有可能会用到.小白我也在工作中用到过.那么好的程序设计,什么时候会用到呢? try...catch 一般用来捕 ...

  10. nyoj 题目36 最长公共子序列

    最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...