当前位置: 首页 > 面试题库 >

Java KeyListener未注册箭头键

马绪
2023-03-14
问题内容

我正在用Java写一个简单的程序,其中包括一个KeyListener,下面是覆盖它们的KeyTyped方法:

@Override
        public void keyTyped(KeyEvent e)
        {
            int key = e.getKeyCode();
            System.out.println("TEST");

            if (key == KeyEvent.VK_KP_LEFT || key == KeyEvent.VK_LEFT)
            {
                System.out.println("LEFT");
                //Call some function
            }
            else if (key == KeyEvent.VK_KP_RIGHT || key == KeyEvent.VK_RIGHT)
            {
                System.out.println("RIGHT");
                //Call some function
            }
        }

当我键入除箭头键以外的其他任何字符(例如“ a”)时,它将TEST按原样打印。但是,当我键入小键盘TEST箭头键时,它只会打印,而当我键入标准箭头键时,它根本不会打印任何内容。这可能是因为我在笔记本电脑上,还是我在某个地方犯了一个愚蠢的错误?


问题答案:

是的,你将看到箭头键响应keyPressed和keyReleased,而不是keyTyped。我的SSCCE:

import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class ArrowTest extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;

   public ArrowTest() {
      setFocusable(true);
      requestFocusInWindow();

      addKeyListener(new KeyAdapter() {

         @Override
         public void keyTyped(KeyEvent e) {
            myKeyEvt(e, "keyTyped");
         }

         @Override
         public void keyReleased(KeyEvent e) {
            myKeyEvt(e, "keyReleased");
         }

         @Override
         public void keyPressed(KeyEvent e) {
            myKeyEvt(e, "keyPressed");
         }

         private void myKeyEvt(KeyEvent e, String text) {
            int key = e.getKeyCode();
            System.out.println("TEST");

            if (key == KeyEvent.VK_KP_LEFT || key == KeyEvent.VK_LEFT)
            {
                System.out.println(text + " LEFT");
                //Call some function
            }
            else if (key == KeyEvent.VK_KP_RIGHT || key == KeyEvent.VK_RIGHT)
            {
                System.out.println(text + " RIGHT");
                //Call some function
            }
         }


      });
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      ArrowTest mainPanel = new ArrowTest();

      JFrame frame = new JFrame("ArrowTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

因此,要解决此问题,如果要侦听箭头事件,请重写keyPressed而不是keyTyped。

或寻求更好的解决方案:使用键绑定

编辑
我的键绑定版本:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class ArrowTest extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;

   public ArrowTest() {
      ActionMap actionMap = getActionMap();
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);

      for (Direction direction : Direction.values()) {
         inputMap.put(direction.getKeyStroke(), direction.getText());
         actionMap.put(direction.getText(), new MyArrowBinding(direction.getText()));
      }
   }

   private class MyArrowBinding extends AbstractAction {
      public MyArrowBinding(String text) {
         super(text);
         putValue(ACTION_COMMAND_KEY, text);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         String actionCommand = e.getActionCommand();
         System.out.println("Key Binding: " + actionCommand);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      ArrowTest mainPanel = new ArrowTest();

      JFrame frame = new JFrame("ArrowTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

enum Direction {
   UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)),
   DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)),
   LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)),
   RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));

   Direction(String text, KeyStroke keyStroke) {
      this.text = text;
      this.keyStroke = keyStroke;
   }
   private String text;
   private KeyStroke keyStroke;

   public String getText() {
      return text;
   }

   public KeyStroke getKeyStroke() {
      return keyStroke;
   }

   @Override
   public String toString() {
      return text;
   }
}


 类似资料:
  • 本文向大家介绍Swift箭头,包括了Swift箭头的使用技巧和注意事项,需要的朋友参考一下 示例 Arrow是Swift中一个优雅的JSON解析库。 它允许在<--运算符的帮助下解析JSON并将其映射到自定义模型类: 示例 斯威夫特模型 JSON文件 制图 用法 安装: 迦太基 可可豆 手动地 只需复制并粘贴Arrow.swift到您的Xcode项目中 https://github.com/s4c

  • 我已经使用jsplumb在to div块之间创建了一个连接。我想在连接线上添加箭头。现在箭头没有显示出来。我对此一无所知。 知道为什么箭没有出现吗?有东西不见了吗?多谢了。 `HTML:ABC XYZ CSS: Javascript:jsPlumb.connect({source:“window20”,target:“window21”,锚点:[“Bottom”,“Top”],连接器:“direc

  • 不鼓励将箭头函数(“lambdas”)传递给 Mocha。Lambdas词法绑定 this,无法访问 Mocha 上下文。例如,以下代码将失败: describe('my suite', () => { it('my test', () => { // should set the timeout of this test to 1000 ms; instead will fail thi

  • ES6标准新增了一种新的函数:Arrow Function(箭头函数)。 为什么叫Arrow Function?因为它的定义用的就是一个箭头: x => x * x 上面的箭头函数相当于: function (x) { return x * x; } 在继续学习箭头函数之前,请测试你的浏览器是否支持ES6的Arrow Function: 'use strict'; ---- var f

  • 当我执行时,我的服务按预期列出,但当我从web或通过功能测试访问我的包时,我得到: 未捕获的PHP异常Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException:“您请求了一个不存在的服务”xx。处理程序”在xx/app/bootstrap。php。缓存行2031{“异常”:“[对象](Symfony\Compo

  • 在64位计算机上运行Visual Studio 2012应用程序时,会显示以下错误消息: 由于以下错误,检索CLSID为{F2D4F4E5-EEA1-46FF-A83B-A270C92DAE4B}的组件的COM类工厂失败:80040154类未注册(HRESULT的异常:0x80040154(REGDB_E_CLASSNOTREG)) 我正在visualstudio中使用Inventor packa