¿Por qué mi Changelistener reacciona solo para JMENU, y no para Jmenuitem?
-
12-11-2019 - |
Pregunta
Ahora, tengo un jmenu, y algunos jmenuitems en él.Quiero que mi programa realice alguna acción cuando el estado de Jmenu y Jmenuitem se cambie a "seleccionado".No uso el mouseOver de Mouseelitener, porque quiero que el usuario pueda navegar en el menú con teclados también.Ahora, escribí este oyente:
class MenuItemListener implements ChangeListener {
@Override
public void stateChanged(ChangeEvent arg0) {
JMenuItem item = (JMenuItem) arg0.getSource();
if(item.isSelected())
System.out.println(item.getText()+" pressed!");
}
}
Cuando agrego este oyente a Jmenu, funciona correctamente, pero cuando lo agrego a Jmenuitem, nada sucede ... Cuando eliminé la instrucción si el oyente reaccione ambos, cuando el menú está seleccionado y deseleccionado, funciona bien para JMENU.así como para jmenuitem.Entonces, como veo, Jmenuitem no puede "pasar" la prueba () isselected (), pero ¿qué puede ser un problema?: S
Solución
Sin ofensa destinada en ninguna dirección, esta es solo una de esas preguntas con un historial
- Requisito inicial: hacer algo cuando un mouse está sobre jmenuitem
- Darling de todos: Mouselistener
-
Sugerencia de desviación inicial (Kudos a @mkorbel!): Changelistener en el botón de botón, revisando la propiedad Rollover
-
Requisito refinado: Dosalgo cuando Jmenuitem acaba de resaltar, tanto del teclado como por el mouse sobre.
- Refinado Darling: ChangElistener en el botón de botón, propiedad no especificada
-
Desviación refinada: ActionListener
-
Requisito actual: Dosalgo cuando se modificó la propiedad JMENU o JMENUITEM "seleccionada".
- Darling actual: no se puede hacer con un oyente, anular ...
- desviaciones actuales: acción, menulistener ...
El correcto y completo (en retrospectiva, sin embargo, como el teclado aún no se mencionó) la respuesta ya estaba disponible en la primera ronda: algunos oyentes semánticos que es "lo suficientemente bajo" para capturar los cambios estatales (los candidatos son rollover , armado, seleccionado, presionado en el nivel de botón de botón) que hacen que los menuitems cambien su estado resaltado . Desafortunadamente, la relación exacta no es bien conocida (para mí, al menos), indocumentada (lea: Lazy Younch No pudo encontrar nada en una mirada rápida) e incluso confundir (de nuevo, para mí), ya que la rollover es falsa siempre (?) para Menuitems
La reacción del experimentalista es .. Intente: A continuación, se encuentra un fragmento de código que escucha y registra los cambios en el estado en algún árbol de menú (simplemente lanzan a un barbar arbitrario y mueve el mouse y navegue por el teclado).
y el ganador es: - Use un ChangElistener y compruebe si la fuente está seleccionada o armada.
ChangeListener ch = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { if (e.getSource() instanceof JMenuItem) { JMenuItem item = (JMenuItem) e.getSource(); if (item.isSelected() || item.isArmed()) { System.out.println("Highlighted: " + item.getActionCommand()); } } } };
Funciona para el teclado y el mouse, ambos JMENU y JMENUITEM
//----------- code snippet to track property changes in menuItem/buttonModel // test menu JMenu menu = new JMenu("Sample menu"); menu.setMnemonic('s'); installListeners(menu); // first menuitem JMenuItem other = menu.add("content1"); installListeners(other); // second menuitem other = menu.add("again + "); installListeners(other); // sub JMenu sub = new JMenu("subMenu"); installListeners(sub); menu.add(sub); // menus in sub other = sub.add("first in sub"); installListeners(other); other = sub.add("second in sub"); installListeners(other); getJMenuBar().add(menu); private void installListeners(JMenuItem menu) { menu.getModel().addChangeListener(getChangeListener()); menu.addChangeListener(getChangeListener()); } private ChangeListener getChangeListener() { ChangeListener ch = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { if (e.getSource() instanceof ButtonModel) { ButtonModel model = (ButtonModel) e.getSource(); System.out.println("from model: " + createStateText(model)); } else if (e.getSource() instanceof JMenuItem) { JMenuItem item = (JMenuItem) e.getSource(); System.out.println(" from item: " + createStateText(item)); } } private String createStateText(ButtonModel model) { String text = model.getActionCommand() + " armed: " + model.isArmed(); text += " selected: " + model.isSelected(); text += " rollover " + model.isRollover(); text += " pressed: " + model.isPressed(); return text; } private String createStateText(JMenuItem model) { String text = model.getActionCommand() + " armed: " + model.isArmed(); text += " selected: " + model.isSelected(); // not supported on JMenuItem nor on AbstractButton // text += " rollover " + model.isRollover(); // text += " pressed: " + model.isPressed(); return text; } }; return ch; }