Question

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?

Was it helpful?

Solution

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)

OTHER TIPS

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

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.

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

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().

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

Block quote Public static void main ()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top