• 如何让natTable表格支持自定义多个右键菜单


    在nebula中,官方默认提供了一个构造natTable的builder类,并且提供了一个debugInfo的默认右键菜单,但是当我们通过官方提供的builder去创建natTable,并且要添加多个右键菜单的时候,显得就不太灵活了,需要自己动手改改了,直接上代码吧:

    1、创建一个抽象的菜单类AbstractMenuConfiguration:

     1 public abstract class AbstractMenuConfiguration implements IMenuItemProvider {
     2 
     3     private final String NAT_EVENT_DATA_KEY = "natEventData"; //$NON-NLS-1$
     4 
     5     @Override
     6     public void addMenuItem(NatTable natTable, Menu popupMenu) {
     7         MenuItem inspectLabelsMenuItem = new MenuItem(popupMenu, SWT.PUSH);
     8         inspectLabelsMenuItem.setText(getMenuName());
     9         inspectLabelsMenuItem.setEnabled(true);
    10         inspectLabelsMenuItem.addSelectionListener(new SelectionAdapter() {
    11             @Override
    12             public void widgetSelected(SelectionEvent e) {
    13                 processEvent(getNatEventData(e));
    14             }
    15         });
    16     }
    17 
    18     private NatEventData getNatEventData(SelectionEvent selectionEvent) {
    19         Widget widget = selectionEvent.widget;
    20         if (widget == null || !(widget instanceof MenuItem)) {
    21             return null;
    22         }
    23 
    24         MenuItem menuItem = (MenuItem) widget;
    25         Menu parentMenu = menuItem.getParent();
    26         Object data = null;
    27         while (parentMenu != null) {
    28             if (parentMenu.getData(this.NAT_EVENT_DATA_KEY) == null) {
    29                 parentMenu = parentMenu.getParentMenu();
    30             } else {
    31                 data = parentMenu.getData(this.NAT_EVENT_DATA_KEY);
    32                 break;
    33             }
    34         }
    35 
    36         return data != null ? (NatEventData) data : null;
    37     }
    38 
    39     protected abstract void processEvent(NatEventData natEventData);
    40 
    41     protected abstract String getMenuName();
    42 }

    2、创建一个自定义PopupMenu构建类CustomerPopupMenuBuilder:

      1 public class CustomerPopupMenuBuilder {
      2 
      3     /**
      4      * The active NatTable instance the context menu should be added to. Needed
      5      * in advance to be able to add custom menu items that need the NatTable
      6      * instance.
      7      */
      8     protected NatTable natTable;
      9 
     10     /**
     11      * The {@link Menu} that is created with this popup menu builder.
     12      */
     13     protected Menu popupMenu;
     14 
     15     /**
     16      * The {@link MenuManager} that is used by this popup menu builder. Can be
     17      * <code>null</code> if plain SWT menu mechanisms are used.
     18      */
     19     protected MenuManager menuManager;
     20 
     21     /**
     22      * Collection of all registered visibility state checkers for configured
     23      * id's.
     24      */
     25     protected final MenuItemStateMap visibility = new MenuItemStateMap();
     26 
     27     /**
     28      * Collection of all registered enablement state checkers for configured
     29      * id's.
     30      */
     31     protected final MenuItemStateMap enablement = new MenuItemStateMap();
     32 
     33     /**
     34      * Creates {@link CustomerPopupMenuBuilder} that builds up a new
     35      * {@link Menu} that is only configurable with this instance of
     36      * {@link CustomerPopupMenuBuilder}. Uses a {@link MenuManager} internally
     37      * to be able to configure visibility and enabled states.
     38      *
     39      * @param parent
     40      *            The active NatTable instance the context menu should be added
     41      *            to.
     42      */
     43     public CustomerPopupMenuBuilder(NatTable parent) {
     44         this(parent, new MenuManager());
     45     }
     46 
     47     /**
     48      * Creates a {@link CustomerPopupMenuBuilder} that builds up a new
     49      * {@link Menu} using the given {@link MenuManager}.
     50      *
     51      * @param parent
     52      *            The active NatTable instance the context menu should be added
     53      *            to.
     54      * @param manager
     55      *            The {@link MenuManager} that should be used to create the
     56      *            {@link Menu}.
     57      */
     58     public CustomerPopupMenuBuilder(NatTable parent, MenuManager manager) {
     59         this.natTable = parent;
     60         this.menuManager = manager;
     61         this.popupMenu = manager.createContextMenu(this.natTable);
     62     }
     63 
     64     /**
     65      * Creates a popup menu builder based on the given menu. Using this enables
     66      * the possibility to use configured context menus from plugin.xml and
     67      * adding NatTable commands programmatically.
     68      * <p>
     69      * As an example you might want to create a PopupMenuBuilder by using a
     70      * configured menu with the id
     71      * <i>org.eclipse.nebula.widgets.nattable.example.contextmenu</i>
     72      * <p>
     73      *
     74      * <pre>
     75      * ISelectionProvider isp =
     76      *         new RowSelectionProvider&lt;?&gt;(selectionLayer, bodyDataProvider, false);
     77      * MenuManager menuManager = new MenuManager();
     78      * menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
     79      * getSite().registerContextMenu(
     80      *         &quot;org.eclipse.nebula.widgets.nattable.example.contextmenu&quot;, menuManager, isp);
     81      * PopupMenuBuilder popupMenu =
     82      *         new PopupMenuBuilder(menuManager.createContextMenu(natTable));
     83      * </pre>
     84      * <p>
     85      * For usage with Eclipse 4 you can use the <code>EMenuService</code> to
     86      * register the menu to a NatTable instance. Afterwards get the menu and
     87      * remove it from the NatTable to avoid the SWT control menu. The generated
     88      * menu carries a {@link MenuManager} in the {@link Menu#getData()} which
     89      * will be used within this {@link CustomerPopupMenuBuilder}.
     90      * </p>
     91      *
     92      * <pre>
     93      * menuService.registerContextMenu(natTable, menuId);
     94      * Menu swtMenu = natTable.getMenu();
     95      * natTable.setMenu(null);
     96      * </pre>
     97      *
     98      * @param natTable
     99      *            The active NatTable instance which might be needed for
    100      *            creation of menu items that need the NatTable instance to
    101      *            work.
    102      * @param menu
    103      *            The registered context menu.
    104      */
    105     public CustomerPopupMenuBuilder(NatTable natTable, Menu menu) {
    106         this.natTable = natTable;
    107         this.popupMenu = menu;
    108 
    109         // if the menu is build up using a MenuManager, remember that for
    110         // further use
    111         if (menu.getData() != null && menu.getData() instanceof MenuManager) {
    112             this.menuManager = (MenuManager) menu.getData();
    113         }
    114     }
    115 
    116     /**
    117      * Adds the menu item provided by the given {@link IMenuItemProvider} to the
    118      * popup menu. You can use this to add your own item to the popup menu.
    119      * <p>
    120      * Items added by this method can not be identified by id, so adding visible
    121      * or enabled state checkers is not possible for these providers.
    122      * </p>
    123      *
    124      * @param menuItemProvider
    125      *            The {@link IMenuItemProvider} that provides the menu item that
    126      *            should be added to the popup menu.
    127      * @return The current {@link CustomerPopupMenuBuilder} with the added item.
    128      */
    129     public CustomerPopupMenuBuilder withMenuItemProvider(IMenuItemProvider menuItemProvider) {
    130         if (this.menuManager == null) {
    131             menuItemProvider.addMenuItem(this.natTable, this.popupMenu);
    132         } else {
    133             this.menuManager.add(new PopupContributionItem(menuItemProvider));
    134         }
    135         return this;
    136     }
    137 
    138     /**
    139      * Adds the menu item provided by the given {@link IMenuItemProvider} to the
    140      * popup menu. You can use this to add your own item to the popup menu.
    141      * <p>
    142      * As items added by this method can be identified via the given id it is
    143      * possible to register visible or enabled state checkers for these
    144      * providers.
    145      * </p>
    146      *
    147      * @param id
    148      *            The id under which the given {@link IMenuItemProvider} should
    149      *            be identifiable.
    150      * @param menuItemProvider
    151      *            The {@link IMenuItemProvider} that provides the menu item that
    152      *            should be added to the popup menu.
    153      * @return The current {@link CustomerPopupMenuBuilder} with the added item.
    154      */
    155     public CustomerPopupMenuBuilder withMenuItemProvider(String id, IMenuItemProvider menuItemProvider) {
    156         if (this.menuManager == null) {
    157             menuItemProvider.addMenuItem(this.natTable, this.popupMenu);
    158         } else {
    159             this.menuManager.add(new PopupContributionItem(id, menuItemProvider));
    160         }
    161         return this;
    162     }
    163 
    164     /**
    165      * Adds the menu item(s) provided by the given {@link ContributionItem} to
    166      * the popup menu. You can use this to add your own item to the popup menu.
    167      * <p>
    168      * This method is only working if the {@link CustomerPopupMenuBuilder} is
    169      * using a {@link MenuManager}.
    170      * </p>
    171      * <p>
    172      * Using this adds support for visibility and enabled states of menu items.
    173      * </p>
    174      *
    175      * @param contributionItem
    176      *            The {@link ContributionItem} that is used to add a menu item
    177      *            to the menu.
    178      * @return The current {@link CustomerPopupMenuBuilder} with the added item.
    179      * @throws IllegalStateException
    180      *             if this {@link CustomerPopupMenuBuilder} does not use a
    181      *             {@link MenuManager}
    182      */
    183     public CustomerPopupMenuBuilder withContributionItem(ContributionItem contributionItem) {
    184         if (this.menuManager == null) {
    185             throw new IllegalStateException("This PopupMenuBuilder is not created using a MenuManager, " //$NON-NLS-1$
    186                     + "therefore ContributionItems can not be added"); //$NON-NLS-1$
    187         } else {
    188             this.menuManager.add(contributionItem);
    189         }
    190         return this;
    191     }
    192 
    193     public CustomerPopupMenuBuilder configureMenuItemProvider(String mid, IMenuItemProvider menuItemProvider) {
    194         return withMenuItemProvider(
    195                 mid,
    196                 menuItemProvider);
    197     }
    198 
    199     /**
    200      * Adds a separator to the popup menu with the given id.
    201      *
    202      * @param id
    203      *            The id to identify the separator. Necessary if there should be
    204      *            visibility constraints for specific separators.
    205      * @return The {@link CustomerPopupMenuBuilder} with an added separator.
    206      * @see MenuItemProviders#separatorMenuItemProvider()
    207      */
    208     public CustomerPopupMenuBuilder withSeparator(String id) {
    209         return withMenuItemProvider(id, MenuItemProviders.separatorMenuItemProvider());
    210     }
    211 
    212     /**
    213      * Builds and returns the created {@link Menu}.
    214      * <p>
    215      * <b>Note:</b> Calling this method will also add a {@link DisposeListener}
    216      * to the NatTable instance to ensure the created {@link Menu} is disposed
    217      * when the NatTable itself gets disposed.
    218      * </p>
    219      *
    220      * @return The {@link Menu} that is created by this builder.
    221      */
    222     public Menu build() {
    223 
    224         this.natTable.addDisposeListener(new DisposeListener() {
    225             @Override
    226             public void widgetDisposed(DisposeEvent e) {
    227                 if (CustomerPopupMenuBuilder.this.popupMenu != null
    228                         && !CustomerPopupMenuBuilder.this.popupMenu.isDisposed())
    229                     CustomerPopupMenuBuilder.this.popupMenu.dispose();
    230             }
    231         });
    232 
    233         return this.popupMenu;
    234     }
    235 
    236     /**
    237      * Associate a visibility {@link IMenuItemState} with the menu item
    238      * identified by the given id.
    239      * <p>
    240      * The visibility state is handled by the internal {@link MenuManager}. If
    241      * no {@link MenuManager} is used, this method will have not effect.
    242      * </p>
    243      * <p>
    244      * For the item to be visible, all associated {@link IMenuItemState} must be
    245      * active OR no {@link IMenuItemState} must be associated with the item.
    246      * </p>
    247      *
    248      * @param id
    249      *            the registered {@link IMenuItemState} will affect the menu
    250      *            item identified by the given id.
    251      * @param state
    252      *            the {@link IMenuItemState} to queried for the visibility state
    253      *            of the menu item with the given id.
    254      * @return This {@link CustomerPopupMenuBuilder} with the visible state
    255      *         checker for the given id.
    256      */
    257     public CustomerPopupMenuBuilder withVisibleState(String id, IMenuItemState state) {
    258         this.visibility.addMenuItemState(id, state);
    259         return this;
    260     }
    261 
    262     /**
    263      * Associate a enabled {@link IMenuItemState} with the menu item identified
    264      * by the given id.
    265      * <p>
    266      * The enabled state is handled by the internal {@link MenuManager}. If no
    267      * {@link MenuManager} is used, this method will have not effect.
    268      * </p>
    269      * <p>
    270      * For the item to be enabled, all associated {@link IMenuItemState} must be
    271      * active OR no {@link IMenuItemState} must be associated with the item.
    272      * </p>
    273      *
    274      * @param id
    275      *            the registered {@link IMenuItemState} will affect the menu
    276      *            item identified by the given id.
    277      * @param state
    278      *            the {@link IMenuItemState} to queried for the enabled state of
    279      *            the menu item with the given id.
    280      * @return This {@link CustomerPopupMenuBuilder} with the enabled state
    281      *         checker for the given id.
    282      */
    283     public CustomerPopupMenuBuilder withEnabledState(String id, IMenuItemState state) {
    284         this.enablement.addMenuItemState(id, state);
    285         return this;
    286     }
    287 
    288     /**
    289      * Wrapper class to build up a {@link ContributionItem} based on a given
    290      * {@link IMenuItemProvider}. If an id is set it is possible to register
    291      * state checkers for enabled and visible state.
    292      */
    293     protected class PopupContributionItem extends ContributionItem {
    294 
    295         private IMenuItemProvider provider;
    296 
    297         public PopupContributionItem(IMenuItemProvider provider) {
    298             this(null, provider);
    299         }
    300 
    301         public PopupContributionItem(String id, IMenuItemProvider provider) {
    302             super(id);
    303             this.provider = provider;
    304         }
    305 
    306         @Override
    307         public void fill(Menu menu, int index) {
    308             List<MenuItem> beforeItems = Arrays.asList(menu.getItems());
    309             this.provider.addMenuItem(CustomerPopupMenuBuilder.this.natTable, menu);
    310             MenuItem[] afterItems = menu.getItems();
    311 
    312             for (MenuItem item : afterItems) {
    313                 if (!beforeItems.contains(item)) {
    314                     // isEnabled() seems to be not called by the framework on
    315                     // opening a menu therefore we set it ourself. For this we
    316                     // also need to ensure isDynamic() returns true for
    317                     // re-rendering.
    318                     item.setEnabled(isEnabled());
    319                 }
    320             }
    321         }
    322 
    323         @Override
    324         public boolean isDynamic() {
    325             return (getId() != null);
    326         }
    327 
    328         @Override
    329         public boolean isEnabled() {
    330             if (getId() != null) {
    331                 Object eventData = CustomerPopupMenuBuilder.this.popupMenu.getData(MenuItemProviders.NAT_EVENT_DATA_KEY);
    332                 if (eventData != null && eventData instanceof NatEventData) {
    333                     return CustomerPopupMenuBuilder.this.enablement.isActive(getId(), (NatEventData) eventData);
    334                 }
    335             }
    336             return true;
    337         }
    338 
    339         @Override
    340         public boolean isVisible() {
    341             if (getId() != null) {
    342                 Object eventData = CustomerPopupMenuBuilder.this.popupMenu.getData(MenuItemProviders.NAT_EVENT_DATA_KEY);
    343                 if (eventData != null && eventData instanceof NatEventData) {
    344                     return CustomerPopupMenuBuilder.this.visibility.isActive(getId(), (NatEventData) eventData);
    345                 }
    346             }
    347             return true;
    348         }
    349 
    350     }
    351 }

    3、实现自定义多右键菜单配置CustomerPopupMenuConfiguration:

     1 public class CustomerPopupMenuConfiguration extends AbstractUiBindingConfiguration {
     2 
     3     private Menu menu;
     4 
     5     private CustomerPopupMenuBuilder customerPopupMenuBuilder;
     6 
     7     public CustomerPopupMenuConfiguration(NatTable natTable) {
     8         this.customerPopupMenuBuilder = new CustomerPopupMenuBuilder(natTable);
     9 
    10     }
    11 
    12     public CustomerPopupMenuConfiguration configureMenuItemProvider(String mid, IMenuItemProvider menuItemProvider) {
    13         this.customerPopupMenuBuilder.configureMenuItemProvider(mid, menuItemProvider);
    14         return this;
    15     }
    16 
    17     public CustomerPopupMenuConfiguration build() {
    18         this.menu = this.customerPopupMenuBuilder.build();
    19         return this;
    20     }
    21 
    22     @Override
    23     public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
    24         uiBindingRegistry.registerMouseDownBinding(
    25                 new MouseEventMatcher(SWT.NONE, null, 3),
    26                 new PopupMenuAction(this.menu));
    27     }
    28 }

    4、后面剩下的就是怎么使用自定义菜单了配置了:

     1 public  class Test{
     2       public void configure(NatTable natTable){
     3      ......  
     4               natTable.addConfiguration(new CustomerPopupMenuConfiguration(natTable).configureMenuItemProvider("addRowMenuItem", new AbstractMenuConfi           guration(){
     5             @Override
     6             protected String getMenuName() {
     7                 return "add";
     8             }
     9             @Override
    10             protected void processEvent(NatEventData natEventData) {
    11                 //处理增加
    12             }
    13         }).configureMenuItemProvider("updateRowMenuItem", new AbstractMenuConfiguration(){
    14             @Override
    15             protected String getMenuName() {
    16                 return "update";
    17             }
    18             @Override
    19             protected void processEvent(NatEventData natEventData) {
    20                     //  处理修改
    21             }
    22         }).configureMenuItemProvider("deleteRowMenuItem", new AbstractMenuConfiguration(){
    23             @Override
    24             protected String getMenuName() {
    25                 return "delete";
    26             }
    27             @Override
    28             protected void processEvent(NatEventData natEventData) {
    29                 //处理删除
    30             }
    31         }).build());
    32      .....  
    33      }      
    34 }

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

  • 相关阅读:
    matlab中怎样计算某元素是否在某个集合中??
    matlab中怎样删除重复元素使得和Python中集合set的功能一样
    Matlab中怎样计算两个向量或矩阵的共同元素或交集
    matlab中怎样由上已知的三角矩阵或下三角矩阵构建对称矩阵??
    Matlab中怎样将.dat格式的文件进行加载转化为一个矩阵??
    matlab中排序(矩阵的行排序及列排序)
    Python中字典嵌套??
    6.面向对象 -类.md
    1.Java基础概念.md
    5.Java中的数组.md
  • 原文地址:https://www.cnblogs.com/jessezeng/p/5070913.html
Copyright © 2020-2023  润新知