2012-08-25 17 views
7

El JMenuBar no comienza mostrando JMenuItem s como seleccionado o mostrando las ventanas emergentes JMenu hasta que se haga clic por primera vez. Después de hacer clic en algún lugar en el JMenuBar, todos estos elementos responden a los movimientos del mouse.Activar JMenuBar al colocar el cursor sobre el elemento

Me gustaría omitir el clic inicial requerido y tenerlo activado automáticamente al pasar el mouse sobre el mouse. ¿Hay alguna forma de hacer esto?

+3

¿Hay alguna buena razón por la que quieres hacer esto? Todas las barras de menús en todas las aplicaciones se comportan así – Robin

+0

Bueno, mi menú tiene un aspecto personalizado y este comportamiento se ajusta de forma más natural. Además, creo que este comportamiento es mucho más interactivo para el usuario. – springcorn

Respuesta

9

La manera es agregar un MouseListener en el JMenu y escuchar en los eventos mouseEntered. En los controladores de eventos, solo tiene que hacer clic en él usando doClick. Por ejemplo,

jMenuFile.addMouseListener(new MouseListener(){ 
    public void mouseEntered(MouseEvent e) { 
     jMenuFile.doClick(); 
    } 
    ... 
}); 

vez mediante programación hace clic en el ratón se introduce, se abre el menú desplegable automáticamente. Para activar un JMenuBar completo, debe agregar un oyente en cada JMenu. Para este propósito, es mejor crear un objeto detector por separado.

que tienen dos opciones de menú en el bar, así que lo hice:

MouseListener ml = new MouseListener(){ 
    public void mouseClicked(MouseEvent e) {} 
    public void mousePressed(MouseEvent e) {} 
    public void mouseReleased(MouseEvent e) {} 
    public void mouseExited(MouseEvent e) {} 
    public void mouseEntered(MouseEvent e) { 
     ((JMenu)e.getSource()).doClick(); 
    } 
    }; 
    jMenuFile.addMouseListener(ml); 
    jMenuHelp.addMouseListener(ml); 

Si usted tiene tantas opciones de menú en la barra, que sólo puede iterar que:

for (Component c: jMenuBar1.getComponents()) { 
    if (c instanceof JMenu){ 
     c.addMouseListener(ml); 
    } 
} 
+0

Entiendo al oyente de mouseEntered, pero ¿cómo se activa todo el JMenuBar del mousentered? – springcorn

+0

acaba de editar por encima de –

+0

Gracias. Eso me puso en el camino correcto, pero creo que esperaba que hubiera una forma más sencilla de hacer esto como jMenuBar.activate(), en lugar de forzar individualmente el clic. Para JMenuItem no se puede llamar a doClick(). En su lugar, creo que la mejor forma de generar este comportamiento es setArmed (verdadero) – springcorn

1

Romano C de la respuesta inicial y aceptada no será AUTO. Cierre el menú con elementos de menú secundarios como parte de JMenuBar.

Ejecutando un ((JMenu) e.getSource()). DoClick(); en el mouseEntered simula el clic en uno de los padres de JMenu, pero no se puede agregar simplemente al método mouseExited ya que el MouseListener se debe adjuntar a los elementos de menú secundarios así como a los padres de JMenu. (Lo cual no ocurre en la asignación normal a MenuBar, solo se conecta a los objetos JMenu padre).

Además, surge un problema al intentar que el oyente MouseExit dispare un método "cerrado" SÓLO cuando el mouse ha abandonado toda la estructura del Menú (es decir, las listas desplegables del menú Niño).

a continuación es una respuesta totalmente funcional tomado de mi aplicación en vivo:

La forma en que resolvió el menú de cerca a cabo ratón era correr una variable booleana "isMouseOut" en la parte superior del constructor para realizar un seguimiento , y luego asigne MouseListener de una manera más amigable para OO para realizar un seguimiento de los múltiples eventos MouseIn-MouseOut a medida que el usuario interactúa con el menú. Lo cual llama a un método de menú separado que actúa sobre el estado del booleano "isMouseOut". La clase implementa MouseListener. Así es como se hace.

Cree una ArrayList agregando primero todos los elementos del menú a esta matriz.Al igual que:

Font menuFont = new Font("Arial", Font.PLAIN, 12); 
    JMenuBar menuBar = new JMenuBar(); 
    getContentPane().add(menuBar, BorderLayout.NORTH); 

// Array of MenuItems 
    ArrayList<JMenuItem> aMenuItms = new ArrayList<JMenuItem>(); 
    JMenuItem mntmRefresh = new JMenuItem("Refresh"); 
    JMenuItem mntmNew = new JMenuItem("New"); 
    JMenuItem mntmNormal = new JMenuItem("Normal"); 
    JMenuItem mntmMax = new JMenuItem("Max"); 
    JMenuItem mntmStatus = new JMenuItem("Status"); 
    JMenuItem mntmFeedback = new JMenuItem("Send Feedback"); 
    JMenuItem mntmEtsyTWebsite = new JMenuItem("EtsyT website"); 
    JMenuItem mntmAbout = new JMenuItem("About"); 

    aMenuItms.add(mntmRefresh); 
    aMenuItms.add(mntmNew); 
    aMenuItms.add(mntmNormal); 
    aMenuItms.add(mntmMax); 
    aMenuItms.add(mntmStatus); 
    aMenuItms.add(mntmFeedback); 
    aMenuItms.add(mntmEtsyTWebsite); 
    aMenuItms.add(mntmAbout); 

entonces iterar sobre la arrayList en esta etapa la adición de un MouseListener usando el for() bucle:

for (Component c : aMenuItms) { 
     if (c instanceof JMenuItem) { 
      c.addMouseListener(ml); 
     } 
    } 

ahora establecido padres JMenu para el MenuBar:

// Now set JMenu parents on MenuBar 
    final JMenu mnFile = new JMenu("File"); 
    menuBar.add(mnFile).setFont(menuFont); 
    final JMenu mnView = new JMenu("View"); 
    menuBar.add(mnView).setFont(menuFont); 
    final JMenu mnHelp = new JMenu("Help"); 
    menuBar.add(mnHelp).setFont(menuFont); 

A continuación, agregue el menú desplegable Ítems hijos a los padres de JMenu:

// Now set menuItems as children of JMenu parents 
    mnFile.add(mntmRefresh).setFont(menuFont); 
    mnFile.add(mntmNew).setFont(menuFont); 
    mnView.add(mntmNormal).setFont(menuFont); 
    mnView.add(mntmMax).setFont(menuFont); 
    mnHelp.add(mntmStatus).setFont(menuFont); 
    mnHelp.add(mntmFeedback).setFont(menuFont); 
    mnHelp.add(mntmEtsyTWebsite).setFont(menuFont); 
    mnHelp.add(mntmAbout).setFont(menuFont); 

Añadir los mouseListeners a los padres JMenu como un paso separado:

for (Component c : menuBar.getComponents()) { 
     if (c instanceof JMenu) { 
      c.addMouseListener(ml); 
     } 
    } 

Ahora que los elementos lineaMenu niño, todos tienen sus propios oyentes, que están separados de los elementos del padre JMenu y el propio BarraDeMenús - Es importante identificar el tipo de objeto dentro de la instanciación MouseListener() para que el menú se abra automáticamente al pasar el mouse (en este ejemplo los 3x JMenu parents) PERO TAMBIÉN evita los errores de excepción hijo y permite la identificación limpia de mouseOUT de la estructura del menú sin intentar monitorear dónde la posición del mouse es. El MouseListener es el siguiente:

MouseListener ml = new MouseListener() { 
     public void mouseClicked(MouseEvent e) { 
     } 

     public void mousePressed(MouseEvent e) { 
     } 

     public void mouseReleased(MouseEvent e) { 
     } 

     public void mouseExited(MouseEvent e) { 
      isMouseOut = true; 
      timerMenuClear(); 
     } 

     public void mouseEntered(MouseEvent e) { 
      isMouseOut = false; 
      Object eSource = e.getSource(); 
      if(eSource == mnHelp || eSource == mnView || eSource == mnFile){ 
       ((JMenu) eSource).doClick(); 
      } 
     } 
    }; 

Lo anterior sólo simula el clic del ratón en el JMenu 'padres' (3x en este ejemplo), ya que son los desencadenantes de los menús desplegables del menú infantil. El método timerMenuClear() llama a la MenuSelectionManager para vaciar cualquier punto selectedpath estaba en vivo en el momento de mouseOut real:

public void timerMenuClear(){ 
    ActionListener task = new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      if(isMouseOut == true){ 
       System.out.println("Timer"); 
      MenuSelectionManager.defaultManager().clearSelectedPath(); 
      } 
     } 
    };   
    //Delay timer half a second to ensure real mouseOUT 
    Timer timer = new Timer(1000, task); 
    timer.setInitialDelay(500);   
    timer.setRepeats(false); 
    timer.start(); 
} 

Me tomó un poco de pruebas, control ¿Qué valores pude acceder dentro de la JVM durante su desarrollo - pero funciona un placer! incluso con menús anidados :) Espero que muchos encuentren este ejemplo completo muy útil.

Cuestiones relacionadas