在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());
.....
}
}

以上就实现了灵活自定义右键菜单。

最新文章

  1. Secondary NameNode:的作用?
  2. MySQL max_allowed_packet设置及问题
  3. 一个App需要的东西
  4. FineUI中Newtonsoft.Json版本报错解决办法
  5. AutoCAD DxfCode组码值说明
  6. python easy_install centos 下安装过程和原理解析
  7. mysql连接错误:Cannot get hostname for your address
  8. SCOI2014省选总结
  9. hive join 优化
  10. 安装使用yii-debug-toolbar,yii框架的调试插件
  11. Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(六)
  12. Django contenttypes 组件
  13. 【C++】满二叉树问题
  14. linux上安装mysql5.7
  15. 小小知识点(一)——利用电脑自带的BitLocker对磁盘加密
  16. 删除GitHub或者GitLab 上的文件夹,git rm -r --ceched 文件夹名 ,提交commit,git push
  17. 2-7-集合运算(A-B)∪(B-A)-线性表-第2章-《数据结构》课本源码-严蔚敏吴伟民版
  18. 我所遭遇过的游戏中间件--Scaleform
  19. Android中的&amp;lt;include&amp;gt;标签和&amp;lt;merge&amp;gt;标签
  20. chkconfig的原理 和添加开机自启动的办法

热门文章

  1. spider_main.py
  2. 内存泄漏分析 mat 使用 activity泄漏
  3. ThinkPad 触控板双指不可以滑动
  4. getElementByName????????,????????,
  5. com.squareup.okhttp.Interceptor
  6. loj2100 「TJOI2015」线性代数
  7. Windows Server 2012 新特性:IPAM的配置
  8. FTP被动模式服务器端开有限的端口
  9. U盘的容量变小了怎么办?
  10. Android之SeekBar总结(一)