为什么KeyBindings,而不是KeyListeners,在以下示例中检测ActionEvents?

时间:2015-06-21 20:53:51

标签: java macos swing keylistener key-bindings

从一本java教科书中,我复制了一个程序,让用户可以使用箭头键在屏幕上移动一段文字。该程序只适用于非OSX操作系统(我用我的mac证实了这一点,并且可能是在java教科书编写器的计算机上运行)。我找到了解决这种差异的解决方案(Java KeyEvents on Mac),它建议我使用KeyBindings而不是ActionListeners来处理事件的触发和监听,其模糊的理由是

  

注意:要定义对特定键的特殊反应,请使用键绑定而不是键侦听器。

虽然我的代码现在运行,但我仍然不理解该决议的基本原理。为什么KeyBindings而不是KeyListeners会检测到Mac arrowkey命令? arrowkey命令不是涉及多个键的“特殊反应”(如Shift + a + b)。

这是我复制的部分,即使用KeyListener的代码

addKeyListener(new KeyListener()
        {

            @Override
            public void keyReleased(KeyEvent e) {

                switch (e.getKeyCode())
                {
                    case KeyEvent.VK_DOWN: 
                        y -= 10;
                        break;
                    case KeyEvent.VK_UP: 
                        y += 10; 
                        break;

                    //.... more code

带有KeyBindings的细分

 class DownAction extends AbstractAction
    {

        @Override
        public void actionPerformed(ActionEvent e) {
            y += 10;
            repaint();
        }
    }

    class UpAction extends AbstractAction
    {

        @Override
        public void actionPerformed(ActionEvent e) {
            y -= 10;
            repaint();
        }
    }
        this.getInputMap().put(KeyStroke.getKeyStroke("DOWN"),"down");
        this.getActionMap().put("down", new DownAction ());
        this.getInputMap().put(KeyStroke.getKeyStroke("UP"),"up");
        this.getActionMap().put("up", new UpAction ());

        // this segment is within a class that extends JPane

1 个答案:

答案 0 :(得分:1)

使用key listener,"组件必须具有键盘焦点。"相比之下,key bindings"考虑了包容层次结构。"您可能在搜索包含层次结构或focus subsystem的工作方式方面遇到了特定于平台的变幻莫测。

作为一个具体示例,LinePanel包含一个ControlPanel,其中包含许多MoveButton个实例。每个MoveButton都有一个移动该行的Action。封闭的ControlPanel 会获得WHEN_IN_FOCUSED_WINDOW地图条目,该条目将匹配的箭头键绑定到点击相应按钮的Action。通过这种方式,即使另一个按钮具有焦点,特定箭头按钮也会显示视觉反馈。