2

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?

Johnydep
  • 6,027
  • 20
  • 57
  • 74

6 Answers6

5

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)

mre
  • 43,520
  • 33
  • 120
  • 170
Harry Joy
  • 58,650
  • 30
  • 162
  • 207
  • -1 ActionListener is _not_ an alternative ... also see my comment to @GETah) +1 for getSource - in sum a zero :-) – kleopatra Dec 21 '11 at 13:19
  • @kleopatra: I suggested ActionListener, because I thought if he only want to do operation on click of menu then no need to add extra methods for that. Adding ActionListener with single method will do the job. That's why I also mentioned my answer that *(Only if you do not want to do operation on menuCanceled and menuDeselected)*. But may be I'm wrong in that as you are saying it's not good idea to add action listener in menu. Also `downvote + upvote = 8 rep.` ;p – Harry Joy Dec 21 '11 at 13:25
  • well, the error is that a ActionListener registered on a JMenu does exactly ... nothing :-) – kleopatra Dec 21 '11 at 13:27
  • @kleopatra: Ok. Strike through that line. :) – Harry Joy Dec 21 '11 at 13:29
2

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

mre
  • 43,520
  • 33
  • 120
  • 170
1

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.

GETah
  • 20,922
  • 7
  • 61
  • 103
  • technically incorrect, the question is about a _JMenu_ not a _JMenuItem_ (refraining from down-voting for now as it probably will turn out that listening to actions indeed will be the real requirement :) – kleopatra Dec 21 '11 at 13:15
0

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

Tamias
  • 173
  • 9
0

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

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • no, a) there's rarely a need to touch a menu's model b) a ButtonGroup has nothing to do with any aspect of the question (will revert if it'll turn out you have the magic future looking eye :-) – kleopatra Dec 21 '11 at 13:17
-1

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

Block quote Public static void main ()