Question

my question in very simple. I have a JPopupMenu that shown two JMenuItem. The only way I have found to know which item are clicked using

class MenuActionListener implements ActionListener {
  public void actionPerformed(ActionEvent e) {
    System.out.println("Selected: " + e.getActionCommand());    
  }
}

but the command e.getActionCommand() print the text inside the item. I would like get an index from 0 to n to known which item are clicked and not the text (that can be modified). Is it possible ?

Was it helpful?

Solution

You Could...

Place each JMenuItem in a Map, with the int value you want

Map<JMenuItem, Integer> menuMap = new HashMap<JMenuItem, Integer>(25);
//...
JMenuItem item1 = ...
menuMap.put(item, 0);
JMenuItem item2 = ...
menuMap.put(item, 1);

Then in the ActionListener, you would simply look it up based on the source of the event...

public void actionPerformed(ActionEvent e) {
    JMenuItem item = (JMenuItem)e.getSource();
    int index = menuMap.get(item);

You Could...

Use a List and determine the index of the JMenuItem within the list...

List<JMenuItem> menuList = new ArrayList<JMenuItem>(25);
//...
JMenuItem item1 = ...
menuList.add(item);
JMenuItem item2 = ...
menuList.add(item);

//...

public void actionPerformed(ActionEvent e) {
    JMenuItem item = (JMenuItem)e.getSource();
    int index = menuList.indexOf(item);

You Could...

Make use of the Action API

public class IndexedAction extends AbstractAction {
    private int index;
    public IndexedAction(int index, String name) {
        this.index = index;
        putValue(NAME, name);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // Use the index some how...
    }
}

//...

JPopupMenu menu = new JPopupMenu();
menu.add(new IndexedAction(0, "Item 1"));
menu.add(new IndexedAction(1, "Item 2"));
menu.addSeparator();
menu.add(new IndexedAction(2, "Item 3"));
menu.add(new IndexedAction(3, "Item 4"));

You Could...

Set the actionCommand property of the items...

JPopupMenu pm = ...;
pm.add("Item 1").setActionCommand("0");
pm.add("Item 2").setActionCommand("1");
menu.addSeparator();
pm.add("Item 3").setActionCommand("2");
pm.add("Item 4").setActionCommand("3");

The problem with this is you're going to have to parse the actionCommand of the ActionEvent back to an int...not a really sound proof solution...

You Could...

Set the clientProperty of each JMenuItem

JPopupMenu pm = ...;
pm.add("Item 1").putClientProperty("keyValue", 0);
pm.add("Item 2").putClientProperty("keyValue", 1);
menu.addSeparator();
pm.add("Item 3").putClientProperty("keyValue", 2);
pm.add("Item 4").putClientProperty("keyValue", 3);

But this gets messy...

public void actionPerformed(ActionEvent e) {
    JMenuItem item = (JMenuItem)e.getSource();
    Object value = item.getClientProperty("keyValue");
    if (value instanceof Integer) {
        int index = ((Integer)value).intValue();

There's probably other solutions, but without knowing why you want to do this, it makes it impossible to make an accurate suggestion...sorry

OTHER TIPS

The code below shows how to get the index of selected JMenuItem:

      class MenuActionListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                JMenuItem menuitem=(JMenuItem) e.getSource();
                JPopupMenu popupMenu =(JPopupMenu) menuitem.getParent();
                int index= popupMenu.getComponentIndex(menuitem);
                System.out.println("index:"+index);
            }
      }

Why can't we do:

menu.getSelectionModel().getSelectedIndex()

which returns an int?

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