Ни в коем случае не обижайтесь, это только один из вопросов с историей
- первоначальное требование: что-то сделать, когда мышь находится над JMenuItem
- для всех, кто дорог: MouseListener
первоначальное отклоняющееся предложение (слава @mKorbel!): ChangeListener на buttonModel, проверка свойства ролловера
уточненное требование: doSomething, когда JMenuItem простовыделено и клавиатурой, и мышью.
- уточненный дорогой: ChangeListener для buttonModel, свойство не указано
уточненное отклонение: ActionListener
текущее требование: сделайте что-нибудь, когда JMenu или JMenuItem «выбрали» свойство изменилось.
- текущий любимый: нельзя сделать с помощью прослушивателя, переопределить ...
- текущие отклонения: действие, MenuListener ...
правильный и полный (хотя задним числом, поскольку клавиатура еще не упоминалась) ответ был доступен уже в первом раунде: некоторый семантический слушатель, который «достаточно низкоуровневый», чтобы фиксировать изменения состояния (кандидаты на опрокидывание, вооружены, выбраны), нажатие кнопки «Уровень модели»), при которой элементы меню меняют свое выделенное состояние.К сожалению, точное отношение не очень хорошо известно (по крайней мере для меня), недокументировано (читай: ленивый я не смог найти ничего при быстром взгляде) и даже сбивает с толку (опять же, мне), поскольку опрокидывание всегда ложно (?)for menuItems
Реакция экспериментатора состоит в том, чтобы .. try: ниже приведен фрагмент кода, который прослушивает и регистрирует изменения состояния в каком-либо дереве меню (просто бросьте в произвольную строку меню, перемещайте мышь и перемещайтесь по клавиатуре),
И победителем является: - используйте ChangeListener и проверьте, выбран ли источник или включен.
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());
}
}
}
};
работает как для клавиатуры, так и для мыши, как JMenu, так и 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;
}