问题
If I have defined JMenu
and JMenuBar
like this:
private JMenuBar jMenuBar;
private JMenu jMenu1;
jMenuBar = new JMenuBar();
jMenu1 = new JMenu();
jMenu1.setText("ABOUT");
//and here add a MenuListener so that i can detect when a menu is clicked:
jMenu1.addMenuListener(this);
jMenuBar.add(jMenu1);
setJMenuBar(jMenuBar);
//and here i implement the menulisteners
public void menuSelected(MenuEvent e) {
//my logic here
}
public void menuDeselected(MenuEvent e) {}
public void menuCanceled(MenuEvent e) {}
Now it works fine. But the problem is if i have more then one menu, how can i distinguish between the two. Like in the menu listener, how would i know the click came from menu1 or another menu 2?
I mean if i have another menu and i add menu listener for this menu as well:
jMenu2.addMenuListener(this);
then i can not distinguish from which menu the click came from. How can i do that?
回答1:
You can use getSource()
method of MenuEvent class. Or you can also add separate listeners to both menus as anonymous class.
public void menuSelected(MenuEvent e) {
//Make sure jMenu1 and jMenu2 are accessible in here.
if(e.getSource()==jMenu1)
operationForMenu1();
else if(e.getSource()==jMenu2)
operationForMenu2();
}
or
jMenu1.addMenuListener(new MenuListener() {
@Override
public void menuSelected(MenuEvent arg0) {
// operation here.
}
@Override
public void menuDeselected(MenuEvent arg0) {
}
@Override
public void menuCanceled(MenuEvent arg0) {
}
});
jMenu2.addMenuListener(new MenuListener() {
@Override
public void menuSelected(MenuEvent arg0) {
// operation here.
}
@Override
public void menuDeselected(MenuEvent arg0) {
}
@Override
public void menuCanceled(MenuEvent arg0) {
}
});
If you choose second option then it will easy to use (removed this as suggested by @Kleopatra in comment)ActionListener
instead of MenuListener
. (Only if you do not want to do operation on menuCanceled and menuDeselected)
回答2:
That is what getSource() is for, which is a method MenuEvent
inherits from EventObject
.
回答3:
You can use ActionListener
instead. Here is how you can capture a click on a menu item
jMenu1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
// Perform action on menu1 clicked here
}
}
If you have more than one menu sharing the same bit of code when clicked then you can refactor the action listener into a separate class.
回答4:
I think that one of ways is add ButtonModel
to JMenuItem
or add JMenuItems
to the ButtonGroup
can solve confortly that too, example for ButtonModel
回答5:
I came here to see if there was anything I preferred to getSource(), and decided to stick with getSource. It's my preference to work with strings (vs comparing objects), so I'm posting my code in case it's helpful to anyone. (I know some people don't like early returns, don't like switch statements, don't like K&R. Again, personal preference, adapt as desired.)
public void menuSelected(MenuEvent evt) {
String menuName;
Object obj = evt.getSource();
if (obj instanceof JMenu) {
JMenu menu = (JMenu) obj;
menuName = menu.getText();
System.out.println(menuName);
} else {
return;
}
switch (menuName) {
case "Edit":
if (undo.hasPreviousState()) {
jMenuItemEditUndo.setEnabled(true);
} else {
jMenuItemEditUndo.setEnabled(false);
}
if (undo.hasNextState()) {
jMenuItemEditRedo.setEnabled(true);
} else {
jMenuItemEditRedo.setEnabled(false);
}
break;
case "Insert":
DefaultListModel<String> listModel = (DefaultListModel<String>) jListTags.getModel();
if (listModel.contains("table")) {
jMenuItemInsertTable.setEnabled(true);
} else {
jMenuItemInsertTable.setEnabled(false);
}
break;
default:
System.out.println("Menu " + menuName + " not a special case in menuSelected");
}
}
Naturally, JMenu(s) that don't addMenuListener() don't even trigger menuSelected().
回答6:
Change the colour of the button or label. simple and short xoxo
Block quote Public static void main ()
来源:https://stackoverflow.com/questions/8589605/menulistener-implementation-how-to-detect-which-jmenu-was-clicked