2011-03-06 27 views
6

En mi aplicación Java swing, he notado que cuando hago clic en un JMenuItem deshabilitado en un JPopupMenu, se oculta el menú, pero no quiero ocultarlo, como si no se hiciera clic en nada. ¿Hay alguna forma de prevenir esto?Cómo evitar que un JMenuItem deshabilitado oculte el menú al hacer clic en él?

----------------------------------->Actualización: muestra añadida Código:

JMenuItem saveMenuItem = new JMenuItem(); 

saveMenuItem.setEnabled(false); 

saveMenuItem.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     saveMenuItemActionPerformed(); 
    } 
}); 
add(saveMenuItem); 

private void saveMenuItemActionPerformed() { 
    System.out.println("Save clicked."); 
} 
+0

¿Puedes mostrar el código que has escrito? – harshit

+0

@harshit: He adjuntado un ejemplo de código para la forma en que inicializo el JMenuItem. No realizo ninguna acción en el evento de clic ... Este menú oculto es solo el comportamiento predeterminado de Java. – Brad

+0

"He adjuntado una muestra de código ...". Para una mejor ayuda antes, publique un SSCCE (http://pscode.org/sscce.html) en lugar de fragmentos de código. –

Respuesta

0

Esto ha sido probado y funciona.

The Look & Feel decide cómo manejar los eventos del mouse en elementos de menú desactivados.De todos modos, puede interceptar los eventos no deseados mediante el uso de un MenuItem personalizado. Sólo tiene que utilizar ese código (copiar/pegar):

public class CustomMenuItem extends JMenuItem { 

    public CustomMenuItem(String text) { 
     super(text); 
    } 

    public CustomMenuItem() { 
     super(); 
    } 

    protected void processMouseEvent(MouseEvent e) { 
     if (isEnabled()) super.processMouseEvent(e); 
    } 
} 

En primer lugar, adaptar el código para satisfacer sus necesidades (opcional).
Finalmente, reemplace cualquier JMenuItem con un CustomMenuItem.

Eso es todo!

+0

@jmendeth ... Sí, esto funciona perfecto. Muchas gracias. – Brad

+0

@Brad de nada –

+0

@jmendeth ... ¿Existe alguna solución similar para los elementos desactivados de JComboBox? – Brad

0

no estoy seguro de cómo evitarlo. pero puede configurar Visible (falso) para evitar que se muestre. Además, si un usuario hace clic en el menú de desactivación, no se llevará a cabo ninguna acción.

+0

Lo siento, no entiendo lo que quieres decir con setVisible (falso)? – Brad

+0

puedes hacer saveMenuItem.setVisible (falso) – harshit

+0

¡Pero quiero que sea visible y deshabilitado! Si hago clic en un elemento deshabilitado, no se realizará ninguna acción, pero el menú se cerrará. Intentalo. – Brad

0

Cuando deshabilita JMenuItem, debe eliminar el ActionListener asociado a ese JMenuItem utilizando el método jMenuItem.removeActionListener(). Si elimina esa acción, no se llamará al oyente y la ventana emergente no desaparecerá. Espero que esto ayude a lograr su objetivo.

0

En resumen, puede hacer esto, pero tendrá que escribir su propio detector de mouse, que puede requerir una gran cantidad de copia & pegar desde el código fuente jdk, lo cual no es una muy buena idea, y estoy no estoy seguro de qué restricciones de licencia pondrá en su código.

Me gustaría empezar la excavación de este método:

javax.swing.plaf.basic.BasicMenuItemUI.Handler#mouseReleased 

que parece ser el punto de entrada en el que el mecanismo de manejo del menú oculta la ventana emergente. Me gustaría echar un vistazo más de cerca a

javax.swing.plaf.basic.BasicPopupMenuUI.MouseGrabber#stateChanged 

EDITAR El desarrollo de respuesta por @Burhan Valikarimwala, probar este apporach: eliminar todos los oyentes de acción de la JMenuItem discapacitados y almacenarlos en alguna estructura temporal estática (digamos que un Map<WeakReference<JMenuItem>, List<MouseListener>>) , de esta manera no ocultará la ventana emergente. Cuando vuelva a habilitar el elemento del menú, agregue todos los oyentes nuevamente. Conviértalo en un método util y será inconsútil.

+0

Demasiado difícil como dices. – Brad

+0

@rad: ver mi edición. –

0

La única solución que podría llegar a, para su problema de un clic en desactivar JMenuItem haciendo que se esconde es a continuación:


import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import javax.swing.JFrame; 
import javax.swing.JMenuItem; 
import javax.swing.JPanel; 
import javax.swing.JPopupMenu; 

public class PopupMenuDisableNoCloseTest extends JPanel implements ActionListener 
{ 
    public static void main(String[] args) 
    { 
     PopupMenuDisableNoCloseTest p = new PopupMenuDisableNoCloseTest(); 
     p.setPreferredSize(new Dimension(200, 300)); 
     p.setBackground(Color.GREEN); 
     JPanel contentPane = new JPanel(); 
     contentPane.add(p); 
     final JFrame f = new JFrame(); 
     final JPopupMenu popup = new JPopupMenu(); 
     final JMenuItem menuItem1 = new JMenuItem("A popup menu item"); 
     menuItem1.addActionListener(p); 
     menuItem1.addMouseListener(new MouseAdapter() 
     { 
      @Override 
      public void mousePressed(MouseEvent e) 
      { 
       System.out.println(" menuItem1 mousePressed e.getPoint()=" + e.getPoint()); 
      } 

      @Override 
      public void mouseReleased(MouseEvent e) 
      { 
       System.out.println(" menuItem1 mouseReleased e.getPoint()=" + e.getPoint()); 
       if(!menuItem1.isEnabled()) 
        popup.setVisible(true); 
      } 
     }); 
     menuItem1.setEnabled(false); 
     popup.add(menuItem1); 
     JMenuItem menuItem2 = new JMenuItem("Another popup menu item"); 
     menuItem2.addActionListener(p); 
     popup.add(menuItem2); 
     MouseListener popupListener = new PopupListener(popup); 
     f.addMouseListener(popupListener); 
     f.setContentPane(contentPane); 
     f.setSize(800, 600); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setVisible(true); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     JMenuItem source = (JMenuItem) (e.getSource()); 
     String s = "Action event detected. Event source: " + source.getText(); 
     System.out.println("s=" + s); 
    } 

    static class PopupListener extends MouseAdapter 
    { 
     JPopupMenu popup; 
     PopupListener(JPopupMenu popupMenu) 
     { 
      popup = popupMenu; 
     } 

     @Override 
     public void mousePressed(MouseEvent e) 
     { 
      maybeShowPopup(e); 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) 
     { 
      maybeShowPopup(e); 
     } 

     private void maybeShowPopup(MouseEvent e) 
     { 
      if(e.isPopupTrigger()) 
      { 
       popup.show(e.getComponent(), 
         e.getX(), e.getY()); 
      } 
     } 
    } 
} 

Básicamente la ocultación ocurre cuando su liberación está dentro de los límites de la JMenuItem , por lo tanto, estamos verificando si está deshabilitada, luego mostramos la ventana emergente de nuevo. Como en este momento ya está decidido que estará oculto. Intenté llamar a super.mouseRelease con un componente externo diferente señalando MouseEvent y consumir el anterior pero no ayuda nada.

De todos modos, esta solución funciona. Enjoy, Boro

0

Creo que en Java7 esto se ha solucionado.

Cuestiones relacionadas