如何在Java中检测按键?

15

我的11岁的儿子正在学习Java,他将要输入一个问题和一些代码。他告诉我在网站上没有找到这个问题的答案。您将会阅读我的编辑版本。非常感谢。

如何在Java中检测按键,我的IDE叫做Eclipse,我创建了一些类。我在互联网上找到了keyconfigofplayer内的代码,并将其更改为扩展播放器类。我希望当我按住某个键时,一个矩形或椭圆形图案可以在屏幕上移动,我该如何做呢?由于某种原因,它无法正确地输入代码,这就是为什么我的导入没有星号并且看起来很奇怪。对此我深感抱歉,请忽略它。我无法修复它:(。以下是我的代码:

窗口代码:

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);
    }
}

我已经尽力注释好类名,这样您就知道它们的意思了。 我从YouTube频道macheads101的Java GUI编程教程第12或11集中复制了keyconfigofplayer的代码。我认为我的问题不在于更新图片,而是在于检测何时按下并释放按键。因此,我应该使用while循环来说明: 如果按下此键,则将x坐标+ 10,直到完成,并不断更新位置。 我还想问,什么时候使用public、private和void?我不理解这些:(,以及我是否正确地执行了扩展玩家实现的操作。当我小心地改变macheads101的代码时,当我完全复制它时它也没有起作用。所以我真的不知道出了什么问题。如果您能回答我的问题并帮助我修改代码,我将不胜感激。最终它会成为一个类似于街机游戏“太空入侵者”或“龙之射手”的射击游戏。


我知道用Youtube视频来学习编程很诱人,但这并不是最好的解决方案。一份书面教程将允许您以更可控的速度了解事物,并查看代码实现。 - Tim B
哦,还有一件事。你可以在Swing中制作游戏,但你会发现它的功能相当有限,因为它更多地设计用于商业类型的软件。要在Java中编写游戏,你真正需要的是一个图形库。例如,这个教程系列使用jME3制作了一个霓虹射击游戏:http://gamedevelopment.tutsplus.com/tutorials/make-a-neon-vector-shooter-in-jmonkeyengine-the-basics--gamedev-11616 - Tim B
9
关于第一段,我必须说你是今年的最佳家长。你的儿子在编程方面有许多潜力,继续鼓励他! - dic19
1
我11岁的儿子正在学习Java,他将输入一个问题和一些代码。他告诉我他在网站上找不到这个问题的答案。您将阅读我编辑过的问题。非常感谢。 好样的,用棍子打败COPPA!像你这样的人让世界转动。 - anon
6个回答

19

阅读有关 java.awt.event.KeyListener 的内容

代码应该像这样:

    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) {
        }
    });

6
GUI(图形用户界面)是事件驱动的。所有发生的事情都由事件驱动。按键是一种事件。组件需要监听事件,并在事件被触发时执行某些操作。您可以在此处详细了解如何编写不同类型的监听器。一些基本的监听器(通过名称)比较容易识别,例如KeyListenerMouseListener。对于按钮按下,ActionListener也很常见。您需要浏览教程并学习不同的监听器。
但请注意,在使用KeyListener时,Swing存在焦点问题,因此最好使用键绑定。正如KeyListener教程中所述:

使用键绑定而不是键侦听器定义特殊反应以响应特定键。

可以在此处找到有关键绑定的教程,也可以在此处看到示例。这是来自示例的gif,显示了使用键绑定进行按键移动矩形的动画:

enter image description here


更新:刚才注意到。
  1. Don't override the paint method of JPanel
  2. Never call repaint() from inside a paint/paintComponent method

    public void paint() {//This is where the graphic is painted to the screen
        repaint();
    }
    
完全删除以上代码。

3

有一个非常好用的库,可以平稳运行并监听全局事件。这是唯一一件在我的电脑上没有任何问题的东西: https://github.com/kwhat/jnativehook

它可以获取系统中的每个事件,对于任何开发者来说都很酷。

你可以像这样使用它:

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) {
    }

}

1

KeyListener

你应该将他的 KeyListener 事件放在你需要它的类中,而不是主方法中!

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!
    }
});

更多关于键盘的信息,请参见:KeyListeners


公共和私有:

现在关于公共和私有,StackOverflow上已经有一个我认为做得很好的答案了!这里


函数/方法和Void:

至于Void,它用于希望不返回任何内容的函数!我不知道您对函数的了解程度如何,但让我举个例子:

int sum;
public int addReturn(int x, int y){
    sum = x +y;
    return sum;
}

这段代码的作用是将给定的两个整数 x 和 y 相加,然后将它们的和作为一个整数返回!

使用 void 关键字,你可以做到:

int sum;
public void add(int x, int y){
    sum = x+ y;
}

这里你没有返回任何东西,但它仍然将 x+y 存储到 sum 中!

所以在你的类中:

int Summation, x = 10, y = 10;
summation = addReturn(x,y); //<-- This will place summation = 10+10 = 20

对于无返回值的函数,您不需要创建变量,因为它不返回任何值,而是在函数内设置值。您只需调用它即可。

add(x,y);

如果您需要更多帮助,请留言! :) 此外,我发现您的儿子在如此年轻的时候对Java如此感兴趣,这真是太棒了。伟大的家长:D


谢谢您提供有关公共、私有和无返回值的信息! - user3343497
公共类keyconfifgofplayer继承自player,实现Actionlistener和keyListener接口。 - user3343497
你需要做的是这样的:public class keyConfigPlayer extends player{ addKeyListener(new KeyListener(){ } } - Shrey
@user3343497,请按照我的帖子中所示实现您的函数!在Eclipse中,它会要求您导入一个类来使用这些函数,您应该允许它 :) - Shrey
我在最后一行关于“enumbody”的东西和VK_SPACE行中遇到错误,它说我需要一个}来完成语句,但我肯定不需要吧? - user3343497
显示剩余3条评论

1
我在你的代码中没有看到任何监听按键或修改x和y位置的内容。只有当你改变x和y并重新绘制屏幕时,圆形才会移动。
你已经设置了面板等,但没有添加任何响应用户操作的内容。你可能需要在某个地方添加一个KeyListener以响应按键事件。这可能在你正在进行的教程中或在之前或之后的教程中。

-1
假设您需要检测按键 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
}

记得使用字符串字面量,因为getKeyChar()方法返回一个字符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接