java中如何实现对键盘上按键的监听?

时间:2023-02-20 10:03:25
我设计了一个小游戏。控制一架潜艇上下左右的移动。
我想实现对键盘的监听,点击→时往右移动等等。
谁对这方面比较懂,举个例子?
我照着学学。

下面程序的功能是点击界面上↑按钮的时候输出一个1,谁能帮我改成点击键盘上的↑按键的时候输出一个1?
JButton upBtn=new JButton("↑");
upBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("1");
}
});

6 个解决方案

#1


这种情况下不应该用按钮来捕获事件,应该用JPanel或JFrame来捕获事件。

用addKeyListener()来注册键盘事件,然后函数可以是:
public void keyReleased(KeyEvent e) {
  System.out.println(e.getKeyCode()); // 找找看↑的KeyCode是多少
}

也可以用常量:KeyEvent.VK_UP 

#2


不是按钮事件,而是键盘事件

引用 1 楼 ldh911 的回复:
这种情况下不应该用按钮来捕获事件,应该用JPanel或JFrame来捕获事件。

用addKeyListener()来注册键盘事件,然后函数可以是:
public void keyReleased(KeyEvent e) {
  System.out.println(e.getKeyCode()); // 找找看↑的KeyCode是多少
}

也可以用常量:……

#3


这是按键事件问题:可以通过KeyListener接口来处理按键事件。

public class KeyEventextends InputEvent表示组件中发生键击的事件。 

当按下、释放或键入某个键时,组件对象(如文本字段)将生成此低级别事件。该事件被传递给每一个 KeyListener 或 KeyAdapter 对象,这些对象使用组件的 addKeyListener 方法注册,以接收此类事件。(KeyAdapter 对象实现 KeyListener 接口。)发生事件时,所有此类侦听器对象都将获得此 KeyEvent。 

“键入键”事件 是高级别事件,通常不依赖于平台或键盘布局。输入 Unicode 字符时生成此类事件,它们被认为是发现字符输入的最佳方式。最简单的情况是,按下单个键(如 "a")将产生键入键事件。但是,字符经常是通过一系列按键(如‘shift’+‘a’)产生的,按下键事件和键入键事件的映射关系可能是多对一或多对多的。键释放通常不需要生成键入键事件,但在某些情况下,只有释放了某个键后才能生成键入键事件(如在 Windows 中通过 Alt-Numpad 方法来输入 ASCII 序列)。对于不生成 Unicode 字符的键是不会生成键入键事件的(如动作键、修改键等等)。 

getKeyChar 方法总是返回有效的 Unicode 字符或 CHAR_UNDEFINED。KEY_TYPED 事件报告字符输入:KEY_PRESSED 和 KEY_RELEASED 事件不必与字符输入关联。因此,可以保证 getKeyChar 方法的结果只对 KEY_TYPED 事件有意义。 

对于按下键和释放键事件,getKeyCode 方法返回该事件的 keyCode。对于键入键事件,getKeyCode 方法总是返回 VK_UNDEFINED。 

“按下键”和“释放键”事件 是低级别事件,依赖于平台和键盘布局。只要按下或释放键就生成这些事件,它们是发现不生成字符输入的键(如动作键、修改键等等)的惟一方式。通过 getKeyCode 方法可指出按下或释放的键,该方法返回一个虚拟键码。 

虚拟键码 用于报告按下了键盘上的哪个键,而不是一次或多次键击组合生成的字符(如 "A" 是由 shift + "a" 生成的)。 

例如,按下 Shift 键会生成 keyCode 为 VK_SHIFT 的 KEY_PRESSED 事件,而按下 'a' 键将生成 keyCode 为 VK_A 的 KEY_PRESSED 事件。释放 'a' 键后,会激发 keyCode 为 VK_A 的 KEY_RELEASED 事件。另外,还会生成一个 keyChar 值为 'A' 的 KEY_TYPED 事件。 

按下和释放键盘上的键会导致(依次)生成以下键事件: 

    KEY_PRESSED
    KEY_TYPED(只在可生成有效 Unicode 字符时产生。)
    KEY_RELEASED
 但在某些情况下(例如,在激活自动重复或输入方法时),该顺序可能会有所不同(并且与平台有关)。 
注: 

不产生 Unicode 字符的键组合(如 F1 和 HELP 键等动作键)不会生成 KEY_TYPED 事件。 
并非所有键盘和系统都能够生成所有的虚拟键码。在 Java 中不会尝试人为地生成这些键。 
虚拟键码不标识物理键:它们取决于平台和键盘布局。例如,使用美国键盘布局时生成 VK_Q 的键在使用法国键盘布局时将生成 VK_A。 
并非所有的字符都有与之关联的 keycode。例如,没有用于问号的 keycode,因为没有在主层上显示问号的键盘。 
为了支持平台无关的动作键处理,Java 平台为某些功能使用少量附加虚拟键常量,否则必须通过解释虚拟键码和修饰符来识别这些功能。例如,对于日文 Windows 键盘,返回 VK_ALL_CANDIDATES 而不是 VK_CONVERT 加 ALT 修饰符。 
正如 Focus Specification 中指定的那样,默认情况下键事件被指派给焦点拥有者。 
警告:除了 Java 语言定义的这些键之外(VK_ENTER、VK_BACK_SPACE 和 VK_TAB),不要依赖 VK_ 常量值。Sun 保留将来根据需要更改这些值的权利,以适应更大范围的键盘。 


具体实现代码:
public KeyboardPanel()
{
addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_DOWN;y+=10;break;
case KeyEvent.VK_UP;y-=10;break;
case KeyEvent.VK_LEFT;y-=10;break;
case KeyEvent.VK_RIGHT;y+=10;break;
deault:keyChar=e.getKeyChar();
}
repaint();
}
});
}

#4


楼上的解释很详细了 主要就是去看看需要重写什么方法  更主要的是记住在你要监听的地方 addKeyListener(new KeyMonitor());

#5


package com.briup.test08;

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

import javax.swing.JButton;
import javax.swing.JFrame;

import javax.swing.JPanel;

public class D extends JPanel{
private JFrame frame;
private Container contentPane;
private JButton button;
public D(){
frame=new JFrame();
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane=frame.getContentPane();
frame.setVisible(true);
init();
}
private void init() {
// TODO Auto-generated method stub
contentPane.setLayout(null);
button=new JButton("按钮");
button.setBounds(50, 50, 80, 30);
contentPane.add(button);
frame.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
System.out.println("实现监听");
 if(e.getKeyCode()==e.VK_UP){
    System.out.println("up");
 }
 System.out.println("实现监听");
 if(e.getKeyCode()==e.VK_DOWN){
    System.out.println("down");
 }
}
});
}
public static void main(String[] args) {
new D();
}
}
我尝试着写了上面这个测试程序。我发现这个程序有的时候键盘可以实现监听,正常的输出,有的时候就不可以了。不知道是什么原因?主程序里面添加了这个键盘监听后从来没有正常过。谁知道?

#6


我测试你要是点击了"按钮",则窗口键盘监听失效。
试着给“按钮”加一监听,每次都从新给frame设置焦点,(表述可能不准,请高手指教)则正常。
添加的代码如下:
1 引入包

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

2 按钮事件
		//---------加了这段
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
frame.requestFocus();
}
});
//---------

#1


这种情况下不应该用按钮来捕获事件,应该用JPanel或JFrame来捕获事件。

用addKeyListener()来注册键盘事件,然后函数可以是:
public void keyReleased(KeyEvent e) {
  System.out.println(e.getKeyCode()); // 找找看↑的KeyCode是多少
}

也可以用常量:KeyEvent.VK_UP 

#2


不是按钮事件,而是键盘事件

引用 1 楼 ldh911 的回复:
这种情况下不应该用按钮来捕获事件,应该用JPanel或JFrame来捕获事件。

用addKeyListener()来注册键盘事件,然后函数可以是:
public void keyReleased(KeyEvent e) {
  System.out.println(e.getKeyCode()); // 找找看↑的KeyCode是多少
}

也可以用常量:……

#3


这是按键事件问题:可以通过KeyListener接口来处理按键事件。

public class KeyEventextends InputEvent表示组件中发生键击的事件。 

当按下、释放或键入某个键时,组件对象(如文本字段)将生成此低级别事件。该事件被传递给每一个 KeyListener 或 KeyAdapter 对象,这些对象使用组件的 addKeyListener 方法注册,以接收此类事件。(KeyAdapter 对象实现 KeyListener 接口。)发生事件时,所有此类侦听器对象都将获得此 KeyEvent。 

“键入键”事件 是高级别事件,通常不依赖于平台或键盘布局。输入 Unicode 字符时生成此类事件,它们被认为是发现字符输入的最佳方式。最简单的情况是,按下单个键(如 "a")将产生键入键事件。但是,字符经常是通过一系列按键(如‘shift’+‘a’)产生的,按下键事件和键入键事件的映射关系可能是多对一或多对多的。键释放通常不需要生成键入键事件,但在某些情况下,只有释放了某个键后才能生成键入键事件(如在 Windows 中通过 Alt-Numpad 方法来输入 ASCII 序列)。对于不生成 Unicode 字符的键是不会生成键入键事件的(如动作键、修改键等等)。 

getKeyChar 方法总是返回有效的 Unicode 字符或 CHAR_UNDEFINED。KEY_TYPED 事件报告字符输入:KEY_PRESSED 和 KEY_RELEASED 事件不必与字符输入关联。因此,可以保证 getKeyChar 方法的结果只对 KEY_TYPED 事件有意义。 

对于按下键和释放键事件,getKeyCode 方法返回该事件的 keyCode。对于键入键事件,getKeyCode 方法总是返回 VK_UNDEFINED。 

“按下键”和“释放键”事件 是低级别事件,依赖于平台和键盘布局。只要按下或释放键就生成这些事件,它们是发现不生成字符输入的键(如动作键、修改键等等)的惟一方式。通过 getKeyCode 方法可指出按下或释放的键,该方法返回一个虚拟键码。 

虚拟键码 用于报告按下了键盘上的哪个键,而不是一次或多次键击组合生成的字符(如 "A" 是由 shift + "a" 生成的)。 

例如,按下 Shift 键会生成 keyCode 为 VK_SHIFT 的 KEY_PRESSED 事件,而按下 'a' 键将生成 keyCode 为 VK_A 的 KEY_PRESSED 事件。释放 'a' 键后,会激发 keyCode 为 VK_A 的 KEY_RELEASED 事件。另外,还会生成一个 keyChar 值为 'A' 的 KEY_TYPED 事件。 

按下和释放键盘上的键会导致(依次)生成以下键事件: 

    KEY_PRESSED
    KEY_TYPED(只在可生成有效 Unicode 字符时产生。)
    KEY_RELEASED
 但在某些情况下(例如,在激活自动重复或输入方法时),该顺序可能会有所不同(并且与平台有关)。 
注: 

不产生 Unicode 字符的键组合(如 F1 和 HELP 键等动作键)不会生成 KEY_TYPED 事件。 
并非所有键盘和系统都能够生成所有的虚拟键码。在 Java 中不会尝试人为地生成这些键。 
虚拟键码不标识物理键:它们取决于平台和键盘布局。例如,使用美国键盘布局时生成 VK_Q 的键在使用法国键盘布局时将生成 VK_A。 
并非所有的字符都有与之关联的 keycode。例如,没有用于问号的 keycode,因为没有在主层上显示问号的键盘。 
为了支持平台无关的动作键处理,Java 平台为某些功能使用少量附加虚拟键常量,否则必须通过解释虚拟键码和修饰符来识别这些功能。例如,对于日文 Windows 键盘,返回 VK_ALL_CANDIDATES 而不是 VK_CONVERT 加 ALT 修饰符。 
正如 Focus Specification 中指定的那样,默认情况下键事件被指派给焦点拥有者。 
警告:除了 Java 语言定义的这些键之外(VK_ENTER、VK_BACK_SPACE 和 VK_TAB),不要依赖 VK_ 常量值。Sun 保留将来根据需要更改这些值的权利,以适应更大范围的键盘。 


具体实现代码:
public KeyboardPanel()
{
addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_DOWN;y+=10;break;
case KeyEvent.VK_UP;y-=10;break;
case KeyEvent.VK_LEFT;y-=10;break;
case KeyEvent.VK_RIGHT;y+=10;break;
deault:keyChar=e.getKeyChar();
}
repaint();
}
});
}

#4


楼上的解释很详细了 主要就是去看看需要重写什么方法  更主要的是记住在你要监听的地方 addKeyListener(new KeyMonitor());

#5


package com.briup.test08;

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

import javax.swing.JButton;
import javax.swing.JFrame;

import javax.swing.JPanel;

public class D extends JPanel{
private JFrame frame;
private Container contentPane;
private JButton button;
public D(){
frame=new JFrame();
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane=frame.getContentPane();
frame.setVisible(true);
init();
}
private void init() {
// TODO Auto-generated method stub
contentPane.setLayout(null);
button=new JButton("按钮");
button.setBounds(50, 50, 80, 30);
contentPane.add(button);
frame.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
System.out.println("实现监听");
 if(e.getKeyCode()==e.VK_UP){
    System.out.println("up");
 }
 System.out.println("实现监听");
 if(e.getKeyCode()==e.VK_DOWN){
    System.out.println("down");
 }
}
});
}
public static void main(String[] args) {
new D();
}
}
我尝试着写了上面这个测试程序。我发现这个程序有的时候键盘可以实现监听,正常的输出,有的时候就不可以了。不知道是什么原因?主程序里面添加了这个键盘监听后从来没有正常过。谁知道?

#6


我测试你要是点击了"按钮",则窗口键盘监听失效。
试着给“按钮”加一监听,每次都从新给frame设置焦点,(表述可能不准,请高手指教)则正常。
添加的代码如下:
1 引入包

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

2 按钮事件
		//---------加了这段
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
frame.requestFocus();
}
});
//---------