TreeViewer的上下文菜单基于所选节点 - SWT

时间:2011-06-01 21:12:34

标签: java eclipse eclipse-plugin swt

我需要在Eclipse插件项目中为TreeViewer创建上下文菜单。但是,菜单不应包含常量项,它们应根据所选节点的类型而有所不同。例如,我的treeViewer具有以下层次结构:

Node A
 |
 --Node B
  |
   --Node C

对于节点A - 我想显示带有动作的菜单,但是对于节点B和C,我不想显示任何内容(没有菜单)。 我设法为节点A创建菜单,但是当选择其他类型的节点时,我无法摆脱它。我的代码如下:

treeViewer.addSelectionChangedListener(
            new ISelectionChangedListener(){
                public void selectionChanged(SelectionChangedEvent event) {
                    if(event.getSelection() instanceof IStructuredSelection) {
                        IStructuredSelection selection = (IStructuredSelection)event.getSelection();            
                        Object o = selection.getFirstElement();     

                        MenuManager menuMgr = new MenuManager();

                        if (o instanceof NodeA){

                            Menu menu = menuMgr.createContextMenu(treeViewer.getControl());
                            treeViewer.getControl().setMenu(menu);
                            getSite().registerContextMenu(menuMgr, treeViewer);

                            menuMgr.add(new SomeAction());

                        }else {
                            //what ?
                        }
                    }

                }
            }   
    );

在else分支上,我尝试在MenuManager上调用dispose()removeAll() ...没有任何作用!

感谢任何帮助,谢谢。

4 个答案:

答案 0 :(得分:11)

正如@jeeeyul所提到的,你应该只创建一个在你的视图中使用的MenuManager。

您可以使用New> Plug-in Project和视图模板在视图中使用查看器获取上下文菜单的示例,但基本上在您的createPartControl(Composite)方法中,您将连接上下文管理器。 / p>

    MenuManager menuMgr = new MenuManager();
    menuMgr.setRemoveAllWhenShown(true);
    menuMgr.addMenuListener(new IMenuListener() {
        public void menuAboutToShow(IMenuManager manager) {
            SampleView.this.fillContextMenu(manager);
        }
    });
    Menu menu = menuMgr.createContextMenu(viewer.getControl());
    viewer.getControl().setMenu(menu);
    getSite().registerContextMenu(menuMgr, viewer);

您的fillContextMenu(MenuManager)方法可以访问您的查看器,因此您可以从中获取当前选择。您可以添加所需的任何操作,甚至可以在使用当前选择更新操作后重新添加操作。

registerContextMenu(*)调用允许扩展点(如org.eclipse.ui.popupMenus和org.eclipse.ui.menus)将项目提供给上下文菜单。

答案 1 :(得分:8)

只需使用单个菜单管理器即可。 不要动态创建菜单管理器。

理论上,你可能尝试过,但它效率低下并且不是一般的方法。

只需创建菜单管理器并添加所需的所有操作。

选择更改后,调用Action#setVisible(true | false)隐藏或显示菜单项。 您还可以使用Action#setEnable启用/禁用菜单项。

PS。 菜单管理器不是菜单GUI(喜欢TreeViewer不是树)

它为菜单(SWT)提供动作(业务逻辑)。它还管理可见性和支持。我们称之为贡献经理。我们可以使用它轻松创建SWT菜单。 (即使我们不了解SWT,我们只需知道我们的业务逻辑:行动)这是JFace的基本理念。

当您向manu管理器添加操作时,操作将包含在ActionContributionItem中。它挂钩动作的状态以更新UI(可见性,启用菜单,按钮,工具栏等)。它还会挂钩UI以在按下时启动动作。

如果你是eclipse的新手,很容易混淆SWT和JFace的角色。

答案 2 :(得分:7)

这就是我这样做的方式:

MenuManager menuMgr = new MenuManager();

        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        menuMgr.addMenuListener(new IMenuListener() {
            @Override
            public void menuAboutToShow(IMenuManager manager) {
                // IWorkbench wb = PlatformUI.getWorkbench();
                // IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
                if (viewer.getSelection().isEmpty()) {
                    return;
                }

                if (viewer.getSelection() instanceof IStructuredSelection) {
                    IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
                    Node object = (Node)selection.getFirstElement();

                    if (object.getModel() instanceof NodeA) {
                        manager.add(new Action();
                    } else if (object.getModel() instanceof NodeB) {

                        manager.add(new OtherAction());

                    }
                }
            }
        });
        menuMgr.setRemoveAllWhenShown(true);
        viewer.getControl().setMenu(menu);

我希望这会有所帮助;)

将菜单管理器的 removeAllWhenShown 属性设置为false非常重要,以便隐藏所有其他节点的操作;)

答案 3 :(得分:0)

假设你知道如何创建Action而你只对上下文菜单感兴趣,下面的例子对我有用,希望这一堆代码可以帮到你

 private void hookContextMenu() {
    MenuManager contextMenu = new MenuManager();
    contextMenu.setRemoveAllWhenShown(true);
    contextMenu.addMenuListener(new IMenuListener() {

        @Override
        public void menuAboutToShow(IMenuManager manager) {



            IStructuredSelection sSelection = (IStructuredSelection) treeViewer.getSelection();

            }
            if(selectedObject instanceof A){
            manager.add(action);
            }

        }
    });