Why my ChangeListener reacts only for JMenu, and not for JMenuItem?

No offense intended in any direction, this is just one of those questions with a history.

No offense intended in any direction, this is just one of those questions with a history initial requirement: do-something when a mouse is over JMenuItem initial everybody's darling: MouseListener initial deviating suggestion (kudos to @mKorbel! ): ChangeListener on the buttonModel, checking the rollover property refined requirement: doSomething when JMenuItem just highlighted, by both keyboard and mouse over. Refined darling: ChangeListener on the buttonModel, property not specified refined deviation: ActionListener current requirement: doSomething when JMenu or JMenuItem "selected" property changed.

Current darling: can't be done with a listener, override ... current deviations: Action, MenuListener ... The correct and complete (in hindsight, though, as the keyboard wasn't yet mentioned) answer was available in the first round already: some semantic listener which is "low-level enough" to capture state changes (candidates are rollover, armed, selected, pressed on the buttonModel level) which make the menuItems change their highlighted state. Unfortunately, the exact relation is not well known (to me, at least), undocumented (read: lazy me couldn't find anything on a quick look) and even confusing (again, to me) as rollover is false always (?) for menuItems The experimentalist's reaction is to .. try: below is a code snippet which listens and logs the state changes on some menu tree (simply throw into an arbitrary menuBar and move the mouse around and navigate by keyboard). And the winner is: - use a ChangeListener and check if the source is either selected or armed.

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("getActionCommand()); } } } }; works for both keyboard and mouse, both JMenu and 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; }.

1 +1 by anonymous up-voter – mKorbel May 12 at 11:33 +1 for well-armed! :-) – trashgod May 12 at 12:37.

This is the expected polymorphic behavior. The isSelected() method of JMenuItem is inherited from AbstractButton, while the same method in Jmenu is overridden so that it "Returns true if the menu is currently selected (highlighted).

BTW +1. – Boro May 12 at 6:30 It depends on what you want to do and how much you want to do it. JMenu has a private ChangeListener that invokes both fireMenuSelected() and fireMenuDeselected(); you could override them and see what turns up.

– trashgod May 12 at 6:56 @Boro: Thanks! Action would be preferred, but menus don't honor the selected property. I can see wanting to do something as the user rolls over each JMenuItem; I'm less sanguine about JMenu.

– trashgod May 12 at 7:04 Oops, I spoke too soon: A MenuListener on your JMenu should work. – trashgod May 12 at 7:25.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions