Now, I have a JMenu, and some JMenuItems in it. I want my program to perform some action when JMenu's and JMenuItem's state is changed to "selected". I don't use MouseLitener's MouseOver, because I want user to be able to navigate in menu using keyboards too. Now, I wrote this listener:
class MenuItemListener implements ChangeListener {
@Override
public void stateChanged(ChangeEvent arg0) {
JMenuItem item = (JMenuItem) arg0.getSource();
if(item.isSelected())
System.out.println(item.getText()+" pressed!");
}
}
When I add this listener to JMenu, it works properly, but when I add it to JMenuItem, nothing happens... When I delete if statement so that listener reacts both, when menu is selected and diselected I works fine for JMenu as well as for JMenuItem. So, as I see, JMenuItem can't "pass" isSelected() test... But what can be a problem? :S
This is the expected polymorphic behavior. The
isSelected()
method ofJMenuItem
is inherited fromAbstractButton
, while the same method inJmenu
is overridden so that it "Returns true if the menu is currently selected (highlighted)."No offense intended in any direction, this is just one of those questions with a history
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 deviation: ActionListener
current requirement: doSomething when JMenu or JMenuItem "selected" property changed.
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.
works for both keyboard and mouse, both JMenu and JMenuItem