如何检测 Java 中的按键按下
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21969954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect a key press in Java
提问by user3343497
My son (aged 11) who is learning Java is going to enter a question and some code. He tells me he has not been able to find the answer to this question on the site. You will be reading my edited version of his question. Many thanks.
我正在学习 Java 的儿子(11 岁)要输入一个问题和一些代码。他告诉我他无法在网站上找到这个问题的答案。您将阅读我对他问题的编辑版本。非常感谢。
How can I detect a keypress in java, My IDE is called eclipse and I have made some classes. I found the code inside keyconfigofplayerof the internet and changed it to extend player class. I want it so when I hold down a key a rectangle or oval will move across the screen, how could I do this? For some reason it wont type the code correctly which is why my imports dont have the asterisk and look wierd. sorry about that. please ignore it. I cant fix that:(. here is my code:
我如何在 Java 中检测按键,我的 IDE 被称为 eclipse,我已经创建了一些类。我在互联网的keyconfigofplayer中找到了代码并将其更改为扩展播放器类。我想要它,所以当我按住一个键时,一个矩形或椭圆形会在屏幕上移动,我该怎么做?出于某种原因,它不会正确键入代码,这就是为什么我的导入没有星号并且看起来很奇怪。对于那个很抱歉。请忽略它。我无法解决这个问题:(。这是我的代码:
code for window:
窗口代码:
import javax.swing.*;
import java.awt.*;
public class window {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.setSize(600, 600);
player p = new player();
f.add(p);
keyconfigofplayer key = new keyconfigofplayer();
p.add(key);
f.add(key);
}
}
//this class is the player graphic
import javax.swing.*;
import java.awt.*;
public class player extends JPanel {
int x = 50;
int y = 50;
public void paint() {//This is where the graphic is painted to the screen
repaint();
}
public void paintComponent(Graphics g) {
//This is where the graphic is 'manufactured'
super.paintComponent(g);
g.setColor(Color.GREEN);
int width = 20;
int height = 20;
g.fillRect(x, y, width, height);
int width2 = 10;
int height2 = 10;
g.fillOval(x, y, width2, height2);
}
}
//the keyconfigofplayer class(where i think the problems are):
//this class is the player graphic
import javax.swing.*;
import java.awt.*;
public class player extends JPanel {
int x = 50;
int y = 50;
public void paint() {//This is where the graphic is painted to the screen
repaint();
}
public void paintComponent(Graphics g) {
//This is where the graphic is 'manufactured'
super.paintComponent(g);
g.setColor(Color.GREEN);
int width = 20;
int height = 20;
g.fillRect(x, y, width, height);
int width2 = 10;
int height2 = 10;
g.fillOval(x, y, width2, height2);
}
}
The classes I have tried to comment well so you know what it means. I got keyconfigofplayer's code from the youtube channel macheads101 how to program GUI in java episode 12 or 11 I think. I think my problem isn't about updating the image, but about detecting when the key is pressed and then released. So maybe I should make a while loop stating that: if this key is pressed down, + 10 to the x coordinates until its done and constantly update the position. I would also like to ask, when to use public, private and void? I dont understand those :( and if Ive done the extends player implements thing correctly. I tried to alter macheads101's code carefully, when I copied it exactly it didn't work too. So I really dont know what is wrong. I would be thankfull if you answered my question and helped me to alter my code. In the end its gonna be a shooter, like the arcade game 'space invaders' or 'dragon shooter'.
我试图对这些课程进行很好的评论,所以你知道这意味着什么。我从 youtube 频道 macheads101 获得了 keyconfigofplayer 的代码,我想如何在 java 第 12 或 11 集编程 GUI。我认为我的问题不在于更新图像,而在于检测何时按下并释放键。所以也许我应该做一个 while 循环,说明:如果按下这个键,+ 10 到 x 坐标直到它完成并不断更新位置。我还想问一下,public、private、void什么时候用?我不明白那些:(如果我已经正确地完成了扩展播放器实现的事情。我试图仔细地更改 macheads101 的代码,当我完全复制它时它也不起作用。所以我真的不知道出了什么问题。我会很感激如果您回答了我的问题并帮助我更改了代码。
回答by user3343497
Read about java.awt.event.KeyListener
阅读 java.awt.event.KeyListener
A code should look like this:
代码应如下所示:
f.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("Key pressed code=" + e.getKeyCode() + ", char=" + e.getKeyChar());
}
@Override
public void keyReleased(KeyEvent e) {
}
});
回答by Tim B
I don't see anything in your code which actually listens for key presses or which modifies the position of x and y. The circle will only move if you change x and y and then repaint the screen.
我在您的代码中没有看到任何实际侦听按键或修改 x 和 y 位置的内容。只有在更改 x 和 y 然后重新绘制屏幕时,圆圈才会移动。
You have set up the panel, etc here but not actually added anything to respond to user action. You will probably need to add a KeyListener
somewhere to respond to key presses. This is probably either in the tutorial you are doing or in a previous or later tutorial.
您已经在此处设置了面板等,但实际上并未添加任何内容来响应用户操作。您可能需要在KeyListener
某处添加一个响应按键的地方。这可能出现在您正在执行的教程中,或者出现在之前或之后的教程中。
回答by Paul Samsotha
So GUI are event driven. Everything that occurs is driven by an event. A key press is an event. A component needs to listen for events, and do something when the event is fired. You can read more about how to write different listeners here. Some of the basic listeners are fairly easy to recognize (by name) like KeyListener
or MouseListener
. ActionListener
is also pretty common for button presses. You'll want to go through the tutorials and learn the different listeners.
所以 GUI 是事件驱动的。发生的一切都是由事件驱动的。按键是一个事件。组件需要监听事件,并在事件被触发时做一些事情。您可以在此处阅读有关如何编写不同侦听器的更多信息。一些基本的侦听器很容易识别(按名称),例如KeyListener
或MouseListener
。ActionListener
按下按钮也很常见。您将需要浏览教程并了解不同的听众。
Note though that with Swing there are focus issues with using a KeyListener
so it is preferred to use key bindings. As stated in the KeyListener
tutorial:
请注意,使用 Swing 时存在焦点问题,KeyListener
因此最好使用键绑定。如KeyListener
教程中所述:
To define special reactions to particular keys, use key bindings instead of a key listener
要定义对特定键的特殊反应,请使用键绑定而不是键侦听器
A tutorial for key bindings can be found hereand an example can been seen here. Here's the gif from the example, showing the movement of rectangle with a key press using key bindings
一种键绑定的教程可以发现这里和一个例子参见这里。这是示例中的 gif,显示了使用按键绑定通过按键移动的矩形
UPDATEjust notice.
更新只是通知。
- Don't override the
paint
method ofJPanel
Nevercall
repaint()
from inside apaint/paintComponent
methodpublic void paint() {//This is where the graphic is painted to the screen repaint(); }
- 不要覆盖的
paint
方法JPanel
永远不要
repaint()
从paint/paintComponent
方法内部调用public void paint() {//This is where the graphic is painted to the screen repaint(); }
Get completely rid of the above code.
完全摆脱上面的代码。
回答by Shrey
KeyListener
按键监听器
You should be putting his KeyListener Event within the class you need it not in the Main Method!
您应该将他的 KeyListener 事件放在您需要的类中,而不是放在 Main 方法中!
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
//This is where you want to implement your key!
if(e.getKeyCode() == KeyEvent.VK_SPACE){
//Fire Gun!
}
....
}
public void keyReleased(KeyEvent e) { //I dont really use these!
}
public void keyTyped(KeyEvent e) { //I dont really use these!
}
});
More on Keys here: KeyListeners
更多关于 Keys 的信息:KeyListeners
Public and Private:
公立和私立:
Now for Public and Private, there is already an answer on StackOVerflow which I think does the job pretty well! Here
现在对于 Public 和 Private,StackOverflow 上已经有一个答案,我认为它可以很好地完成工作!这里
Functions/Methods and Void:
函数/方法和空:
As for Void, It is used in functions where you wish to return nothing! I do not know how well you know about functions but let me give you an example:
至于 Void,它用在你不想返回任何东西的函数中!我不知道您对函数了解多少,但让我举个例子:
int sum;
public int addReturn(int x, int y){
sum = x +y;
return sum;
}
What this does is it adds the two ints given as x and y and then returns the sum as an integer!
它的作用是将 x 和 y 给出的两个整数相加,然后以整数形式返回总和!
With void what you can do is:
使用 void 你可以做的是:
int sum;
public void add(int x, int y){
sum = x+ y;
}
Here you return nothing but it still stores x+y into sum!
在这里你什么都不返回,但它仍然将 x+y 存储到 sum 中!
So in your class:
所以在你的课上:
int Summation, x = 10, y = 10;
summation = addReturn(x,y); //<-- This will place summation = 10+10 = 20
For the void function you do not need to make a variable since it doesnt return a value, rather it sets the value within the function. All you need to do is call it
对于 void 函数,您不需要创建变量,因为它不返回值,而是在函数内设置值。你需要做的就是调用它
add(x,y);
If you need more help just comment! :) Also I find it awesome that your son is so interested in Java at such a young age. Great Parenting :D
如果您需要更多帮助,请发表评论!:) 另外,我觉得您儿子这么年轻就对 Java 如此感兴趣,这真是太棒了。伟大的育儿:D
回答by Rav
There's a great library which works smoothly and it listens to global events. It's the only thing which worked without any issues for me: https://github.com/kwhat/jnativehook
有一个很棒的库,可以顺利运行,并且可以侦听全局事件。这是唯一对我没有任何问题的工作:https: //github.com/kwhat/jnativehook
It grabs every event in the system, pretty cool for any development.
它抓取系统中的每个事件,对于任何开发来说都非常酷。
You can use it like this:
你可以这样使用它:
package main;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
class MyKeyboard implements NativeKeyListener {
public static void main(String[] args) {
try {
GlobalScreen.registerNativeHook();
} catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
GlobalScreen.addNativeKeyListener(new MyKeyboard());
// Now press any keys and look at the output
}
@Override
public void nativeKeyPressed(NativeKeyEvent e) {
}
@Override
public void nativeKeyTyped(NativeKeyEvent nke) {
}
@Override
public void nativeKeyReleased(NativeKeyEvent nke) {
}
}
回答by InfinitePower563
Suppose you need to detect the key f, use this:
假设您需要检测键 f,请使用以下命令:
//packageStatement
import javax.swing.*;
import java.awt.event.*;
//more imports
public class window {
//code
f.addKeyListener(new KeyListener() {
@Override
public void KeyTyped(KeyEvent e) {
if(e.getKeyChar == 'f'){
//code
}
}
//more code
});
//more code
}
Remember to use the string literal, because the getKeyChar() method returns a char.
请记住使用字符串文字,因为 getKeyChar() 方法返回一个字符。