2011-06-01 63 views
9

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

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分支我试着打电话给dispose()removeAll()在MenuManager ...没有什么工作!

任何帮助表示赞赏,谢谢。

回答

7

只需使用单一的菜单管理。 请勿动态制作菜单管理器。

从理论上讲,你可能试过了,但效率不高,不是一般的方法。

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

当选择已被改变时,调用Action#setVisible(true | false)来隐藏或显示菜单项。 您也可以使用行动#setEnable启用/禁用菜单项。

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

它为Actions(业务逻辑)提供菜单(SWT)。它还管理可见性和启用。我们称之为贡献管理器。我们可以用这个创建一个SWT菜单。 (即使我们不知道SWT,我们只需要知道,只有我们的业务逻辑:动作),这是一个在JFace的基本思想。

当您将操作添加到manu管理器时,操作将使用ActionContributionItem包装。它挂钩动作的状态更新UI(知名度,启用菜单,按钮,工具栏等)。它还会在UI按下时启动操作。

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

+0

谢谢你的提示,现在我创建菜单一次,然后在选择的情况下,我打电话action.setEnabled(假)。这工作正常,但我没有找到一个Action的setVisible方法。我想在选择其他节点而不是灰色时隐藏它。谢谢 – AndaP 2011-06-02 17:28:08

+1

如果您添加包含您的操作的ActionContributionItems,它们有一个'setVisible(boolean)'方法。但是你应该选择'setRemoveAllWhenShown(*)'或更新'ActionContributionItems'的可见性,因为它们是不同的方法。 – 2011-06-03 01:56:10

11

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

您可以使用新建>插件项目和视图模板来获取视图中使用查看器的上下文菜单示例,但基本上在您的createPartControl(Composite)方法中,您可以连接上下文管理器。

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扩展点,有助于项目的上下文菜单。

+0

是的,我现在正在使用这种方法。在我的其他观点中,我只是这样创建它的。但我真正担心的是如何更改菜单的内容。 – AndaP 2011-06-02 17:29:23

+0

每个菜单SWT.Show事件都会调用fillContextMenu(*)。您可以每次在该方法中更改菜单的内容。 – 2011-06-03 01:53:56

6

这就是我的方式做到这一点:

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,以隐藏所有其他很重要节点行动;)

0

假设你知道如何创建行动,你只有下面的例子为我工作希望这一串代码将帮助您

感兴趣的上下文菜单
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); 
      } 

     } 
    });