如何让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封装了支持自定义列 ...
随机推荐
- UOJ #2321. 「清华集训 2017」无限之环
首先裂点表示四个方向 一条边上都有插头或者都不有插头,相当于满足流量平衡 最大流 = 插头个数*2时有解 然后求最小费用最大流 黑白染色分别连原点汇点
- MySQL数据库基础总结
来源: 实验楼 链接: https://www.shiyanlou.com/courses/9 一.开发准备 # 打开 MySQL 服务 sudo service mysql start #使用 ro ...
- 4G来临,短视频社交分享应用或井喷
因为工作的原因,接触短视频社交应用的时间相对较多,不管是自家的微视,还是别人家的Vine.玩拍.秒拍等,都有体验过.随着时间的推移,我愈发感受到有一股似曾相识的势能正在某个地方慢慢积聚,直到今天我才猛 ...
- 《Cracking the Coding Interview》——第9章:递归和动态规划——题目2
2014-03-20 02:55 题目:从(0, 0)走到(x, y),其中x.y都是非负整数.每次只能向x或y轴的正方向走一格,那么总共有多少种走法.如果有些地方被障碍挡住不能走呢? 解法1:如果没 ...
- CentOS搭建pptpd服务笔记
pptpd.rpm 包下载.http://poptop.sourceforge.net/yum/stable/packages/ 参考资料:http://www.oschina.net/questio ...
- python的inspect模块
一.type and members 1. inspect.getmembers(object[, predicate]) 第二个参数通常可以根据需要调用如下16个方法: 返回值为object的所有成 ...
- Python 快速部署安装所需模块
需求 我们需要在拷给别人或者提交至服务器也用同样的模块,好保持和开发的一样,所以我们需要自己手动写配置模块信息. 方法 在根目录下创建一个 requirements.txt 文件 里面写 模块名== ...
- python练习题及实现--文件处理、date日期
练习题作者:Vamei 出处:http://www.cnblogs.com/vamei http://www.cnblogs.com/vamei/archive/2012/07/19/2600135. ...
- 孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3
孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十天. 今天继续学习mongoDB的简单操作, ...
- hnust 最小的x
问题 G: 最小的x 时间限制: 1 Sec 内存限制: 128 MB提交: 2347 解决: 1155[提交][状态][讨论版] 题目描述 TSQ对DK进行地狱式训练,找出满足下面公式的最小的x ...