Реализация MenuListener, как определить, какой JMenu был нажат?

Если бы я определил JMenu а также JMenuBar как это:

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) {}

Теперь все отлично работает. Но проблема в том, что если у меня есть более одного меню, как я могу различить два? Как в слушателе меню, как я узнаю, что щелчок поступил из меню 1 или другого меню 2?

Я имею в виду, если у меня есть другое меню, и я добавляю прослушиватель меню для этого меню:

jMenu2.addMenuListener(this);

тогда я не могу отличить, из какого меню пришел щелчок. Как я могу это сделать?

6 ответов

Решение

Ты можешь использовать getSource() метод класса MenuEvent. Или вы также можете добавить отдельных слушателей в оба меню как анонимный класс.

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();
}

или же

   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) {
        }
    });

Если вы выберете второй вариант, он будет прост в использовании ActionListener вместо MenuListener, (Только если вы не хотите выполнять операции с menuCanceled и menuDeselected) (убрал это, как предложено @Kleopatra в комментарии)

Что это getSource() для, который является методом MenuEvent наследуется от EventObject,

Ты можешь использовать ActionListener вместо. Вот как вы можете захватить клик по пункту меню

 jMenu1.addActionListener(new ActionListener(){
  public void actionPerformed(ActionEvent e) {
    // Perform action on menu1 clicked here
  }
 }

Если у вас есть несколько меню, использующих один и тот же бит кода при щелчке, вы можете преобразовать прослушиватель действий в отдельный класс.

Я думаю, что один из способов это добавить ButtonModel в JMenuItem или добавить JMenuItems к ButtonGroup может решить, что тоже, пример для ButtonModel

Я пришел сюда, чтобы посмотреть, есть ли что-нибудь, что я предпочел бы getSource(), и решил придерживаться getSource. Я предпочитаю работать со строками (вместо сравнения объектов), поэтому я публикую свой код на случай, если он кому-нибудь пригодится. (Я знаю, что некоторым людям не нравятся ранние возвращения, не нравятся заявления о переходе, не нравятся K&R. Опять же, личные предпочтения, адаптируйся по желанию.)

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");
    }
}

Естественно, JMenu(s), которые не добавляют addMenuListener(), даже не вызывают menuSelected().

Измените цвет кнопки или метки. простой и короткий xoxo

Цитировать блок Public static void main ()

Другие вопросы по тегам