将 keylistener 添加到 JMenuBar

Adding a keylistener to a JMenuBar

我有以下 JMenuBar 代码。如何将我的关键侦听器 CustomKeyListener 添加到整个 JMenuBar?

package UI;

import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.*;
import java.awt.Point;
import java.awt.font.*;
import UI.*;

public class GuiDMenuBar extends JMenuBar
{
    JMenu m_file,m_code;
    JMenuItem mi_f_new,mi_f_open;

    public GuiDMenuBar()
    {
        setBorderPainted(true);
        makeFileMenu();
        makeCodeButton();

    }

    void makeFileMenu()
    {
        m_file = new JMenu("File");
        m_file.setMnemonic('F');

        mi_f_new = new JMenuItem("New");
        mi_f_new.setMnemonic('N');
        mi_f_open = new JMenuItem("Open");
        mi_f_open.setMnemonic('O');

        mi_f_new.setAccelerator(KeyStroke.getKeyStroke("control N"));
        mi_f_open.setAccelerator(KeyStroke.getKeyStroke("control O"));

        m_file.add(mi_f_new);
        m_file.add(mi_f_open);

        add(m_file);
    }

    void makeCodeButton()
    {
        m_code = new JMenu("Code");
        m_code.setMnemonic('C');

        add(m_code);
    }

    public void addListeners(ActionListener al)
    {
        mi_f_new.addActionListener(al);
        mi_f_open.addActionListener(al);
    }

    class CustomKeyListener implements KeyListener
    {
        @Override
        public void keyTyped(KeyEvent e)
        {
            System.out.println("Type");
        }

        @Override
        public void keyPressed(KeyEvent e)
        {
            System.out.println("Press");
        }

        @Override
        public void keyReleased(KeyEvent e)
        {
            System.out.println("Release");
        }
    }
}

我试过添加

    m_code.setFocusable(true);
    m_code.addKeyListener(new CustomKeyListener());

void makeCodeButton 但是,当为那个 JMenu 输入任何内容时,它并没有出现。这就是为什么我希望将它添加到整个 JMenuBar。

编辑以显示完整的 CustomKeyListener

class CustomKeyListener implements KeyListener
{
    Robot Roby = null;

    @Override
    public void keyTyped(KeyEvent e)
    {
        char c = e.getKeyChar();
        if(c==KeyEvent.VK_ENTER)
        {
            if(m_code.isSelected())
            {
                try
                {
                    Roby = new Robot();
                }

                catch(AWTException awte)
                {
                    awte.printStackTrace();
                }

                clcikComponent(m_file);
            }
        }

        System.out.println("Type");
    }

    @Override
    public void keyPressed(KeyEvent e)
    {
        System.out.println("Press");
    }

    @Override
    public void keyReleased(KeyEvent e)
    {
        System.out.println("Release");
    }

    public void clcikComponent(Component comp)
    {
        Point p = comp.getLocationOnScreen();
        System.out.println(p);

        Roby.mouseMove(p.x,p.y);
        Roby.mousePress(MouseEvent.BUTTON1_MASK);
        Roby.mouseRelease(MouseEvent.BUTTON1_MASK);
    }
}

我仍然认为这是个坏主意。作为一名用户,如果发现在一个菜单上使用 Enter 键会调用一个 Action,而在其他菜单上却不执行任何操作,我会感到非常困惑。我在评论中给出的建议是一个更好的解决方案。

但是,我很好奇为什么它不起作用,我发现当显示菜单时焦点实际上在 JRootPane 上(并且事件只被调度到具有焦点的组件)。因此,您可以将 KeyListener 添加到根窗格。

不过,还有一种更简单的方法。您可以使用 JMenu.addMenuKeyListener(...) 方法。该接口与 KeyListener 相同,只是所有方法的名称中都包含 "menu"。