MenuListener Implementation, how to detect which J

2020-07-22 09:22发布

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?

6条回答
▲ chillily
2楼-- · 2020-07-22 10:02

That is what getSource() is for, which is a method MenuEvent inherits from EventObject.

查看更多
太酷不给撩
3楼-- · 2020-07-22 10:07

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 ActionListener instead of MenuListener. (Only if you do not want to do operation on menuCanceled and menuDeselected) (removed this as suggested by @Kleopatra in comment)

查看更多
Deceive 欺骗
4楼-- · 2020-07-22 10:11

Change the colour of the button or label. simple and short xoxo

Block quote Public static void main ()

查看更多
We Are One
5楼-- · 2020-07-22 10:20

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楼-- · 2020-07-22 10:21

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.

查看更多
萌系小妹纸
7楼-- · 2020-07-22 10:22

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

查看更多
登录 后发表回答