2011-06-01 8 views
9

Necesito crear un menú contextual para un TreeViewer en un proyecto de plugin de Eclipse. Sin embargo, el menú no debe contener elementos constantes, sino que deben variar según el tipo de nodo que se seleccione. Por ejemplo, mi treeViewer tiene la siguiente jerarquía:Menú contextual para TreeViewer basado en el nodo seleccionado - SWT

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

para el nodo A - Quiero mostrar un menú con una acción, pero para los nodos B y C no quiero demostrar nada (sin menú). Logré crear el menú para el nodo A, pero luego no puedo deshacerme de él cuando se selecciona otro tipo de nodo. Mi código es el siguiente:

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 ? 
         } 
        } 

       } 
      } 
    ); 

En la rama más que trataron de llamar dispose(), removeAll() en el MenuManager ... nada funciona!

Se agradece cualquier ayuda, gracias.

Respuesta

7

Simplemente use el Administrador de menús único. No hagas el Administrador de menús dinámicamente.

en teoría, es posible que lo haya intentado, pero es ineficiente y no es de manera general.

Simplemente haga un Administrador de menús y agregue todas las acciones que necesite.

cuando se ha cambiado la selección, llame a Action # setVisible (true | false) para ocultar o mostrar los elementos del menú. También puede usar Action # setEnable para habilitar/deshabilitar el elemento del menú.

ps. El Administrador de menús no es un menú GUI (le gusta TreeViewer no es un árbol)

Contribuye Acciones (lógica comercial) al Menú (SWT). Y también administra la visibilidad y la habilitación. Llamamos a este Administrador de contribuciones. Podemos crear un menú SWT muy fácil con esto. (incluso nosotros no sabemos sobre SWT, solo tenemos que conocer nuestra lógica comercial: Acción). Es una idea fundamental en JFace.

Cuando agrega una acción en manu manager, la acción se ajustará con ActionContributionItem. Engancha el estado de la acción para actualizar la interfaz de usuario (visibilidad, habilitación del menú, botón, barra de herramientas, etc.). También engancha la interfaz de usuario para iniciar la acción cuando se presiona.

Si es nuevo en eclipse, es fácil confundir el papel de SWT y JFace.

+0

gracias por las sugerencias, ahora estoy creando el menú una vez y luego, en caso de una selección, llamo action.setEnabled (false). Esto funciona bien, pero no encontré un método setVisible para Action. Me gustaría ocultarlo cuando se selecciona otro nodo en lugar de volverlo gris. Gracias – AndaP

+1

Si agrega 'ActionContributionItems' que contienen sus acciones, tienen un método' setVisible (boolean) '. Pero debe elegir 'setRemoveAllWhenShown (*)' o actualizar la visibilidad de 'ActionContributionItems' ya que son enfoques diferentes. –

11

Como mencionó @jeeeyul, solo debe crear un MenuManager para usar dentro de su vista.

Puede usar New> Plug-in Project y la plantilla de vista para obtener un ejemplo de un menú contextual en una vista usando un visor, pero básicamente en su método createPartControl(Composite) conectará su administrador de contexto.

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); 

Su método fillContextMenu(MenuManager) tendrá acceso a su visor, para que pueda obtener la selección actual de eso. Puede agregar cualquier acción que desee, incluso volver a agregar acciones después de actualizarlas con la selección actual.

La llamada registerContextMenu(*) permite que puntos de extensión como org.eclipse.ui.popupMenus y org.eclipse.ui.menus contribuyan elementos a su menú contextual.

+0

Sí, estoy usando este enfoque ahora. En mis otros puntos de vista, lo creé así solo una vez. Pero mi verdadera preocupación era cómo cambiar el contenido del menú. – AndaP

+0

fillContextMenu (*) se llama en cada evento SWT.Show de menú. Puede cambiar el contenido del menú cada vez en ese método. –

6

Esa es la manera de hacerlo:

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); 

espero que esto ayuda;)

Es importante establecer removeAllWhenShown propiedad del gestor de menús a falso, con el fin de ocultar todos los demás acciones de nodos;)

0

Supongamos que sabe cómo crear acción y que solo le interesa el menú contextual siguiente ejemplo funcionó para mí espero que este grupo de código lo ayude

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); 
      } 

     } 
    }); 
Cuestiones relacionadas