Слушатель действий Java в меню, а не в пункте меню

Мне нужно просветление.

как добавить событие actionListener для привязки к меню, а не для привязки к ПУНКТУ меню, вот демонстрационный код, который работает (в menuITEM)..

menuFileItem.addActionListener(
            new ActionListener(){
                public void actionPerformed(ActionEvent e)
                {
                    System.out.println("It works");
                }
            }
        );

но когда я пытаюсь сделать то же самое, но только в самом МЕНЮ, это не работает!

menuFile.addActionListener(
            new ActionListener(){
                public void actionPerformed(ActionEvent e)
                {
                    System.out.println("Plz work... :( ");
                }
            }
        );

можно ли добавить слушателя в меню? Я учил, что слушатель может быть добавлен ко всему.


person Игор Рајачић    schedule 20.02.2012    source источник


Ответы (4)


Вы можете добавить ActionListener к JMenu, так как этот метод унаследован от AbstractButton. (документация JMenu)

JMenu menu = new JMenu("MyMenu");
menu.addActionListener(new ActionListener(){...});

Но он не предназначен для использования таким образом: JMenu игнорирует ActionEvent . Вместо этого вы должны использовать MenuEvent и MenuListener.

JMenu menu = new JMenu("MyMenu");
menu.addMenuListener(new MenuListener() {

        @Override
        public void menuSelected(MenuEvent e) {
            System.out.println("menuSelected");

        }

        @Override
        public void menuDeselected(MenuEvent e) {
            System.out.println("menuDeselected");

        }

        @Override
        public void menuCanceled(MenuEvent e) {
            System.out.println("menuCanceled");

        }
    });
person TPete    schedule 20.02.2012
comment
я сделал это, я объявил меню перед конструктором и создал его в конструкторе этого класса, и когда я пытаюсь реализовать menu.addActionListener ..... это не работает. Можете ли вы предоставить рабочий пример вашего решения для этого. - person Игор Рајачић; 20.02.2012
comment
РАБОТАЕТ! благодарю вас!! я только что стал умнее для 1 метода... :D шутка... большое спасибо, теперь мое приложение будет выглядеть более плавно.. я начал работать с java несколько дней назад, с нуля.. так что я нахожусь в фазе обучения в настоящее время. ЕЩЕ РАЗ СПАСИБО ДРУГ! Будьте здоровы! :) - person Игор Рајачић; 20.02.2012

Я использую этот addMouseListener(), потому что, когда вы щелкаете по JMenu, он помечает его синим цветом и сразу после этого выполняет событие.

Я думаю, что это тот эффект, который вы хотите.

Здесь это работает с использованием этого кода: я объявляю:

JMenu jmCadastrar = new JMenu("Cadastrar");

jmCadastrar.addMouseListener(new MouseListener() {

        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseClicked(MouseEvent e) {
            // TODO Auto-generated method stub
            System.exit(0);
        }
    });

}
person Carlos Kafka    schedule 31.08.2014
comment
Благодарю вас! Это решение также работает с несколькими JMenus. - person Pedro; 09.12.2020

Если вы создали экземпляр класса JMenu для создания объекта меню, попробуйте метод addMenuListener().

person zari    schedule 20.02.2012
comment
это звучит интересно, можете ли вы привести рабочий пример? я никогда не использовал этот метод. - person Игор Рајачић; 20.02.2012
comment
Конечно. Ниже приведен код, который вы можете заполнить. JMenu menuFileItem= новый JMenu(); menuFileItem.addMenuListener( new MenuListener(){ public void menuSelected(MenuEvent e) { throw new UnsupportedOperationException(пока не поддерживается.); } public void menuDeselected(MenuEvent e) { throw new UnsupportedOperationException(пока не поддерживается.); } public void menuCanceled (MenuEvent e) { throw new UnsupportedOperationException (пока не поддерживается.); } } ); - person zari; 20.02.2012

основываясь на предыдущих ответах, я добавил в решение дополнительный key listener.

Вот удобная функция:

public static void bind(JMenu menu, ActionListener listener) {

        menu.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                listener.actionPerformed(new ActionEvent(e.getSource(), ActionEvent.ACTION_PERFORMED, "Delegate"));
            }
        });

        menu.addMenuKeyListener(new MenuKeyListener() {

            @Override
            public void menuKeyPressed(MenuKeyEvent e) {

                if(e.getKeyCode() != KeyEvent.VK_ENTER){
                    return;
                }

                // Find out if the menu is the currently selected menu element
                MenuElement[] selectionPath = e.getMenuSelectionManager().getSelectedPath();

                // Because the JMenu will open a popup menu, the menu is the penultimate element in the path
                if (selectionPath.length < 2) {
                    return;
                }

                MenuElement selectedMenu = selectionPath[selectionPath.length - 2];

                if (selectedMenu == menu) {
                    listener.actionPerformed(new ActionEvent(e.getSource(), ActionEvent.ACTION_PERFORMED, "Delegate"));
                }
            }

            @Override
            public void menuKeyTyped(MenuKeyEvent e) {}

            @Override
            public void menuKeyReleased(MenuKeyEvent e) {}
        });
    } 
person F. Weise    schedule 29.12.2016