java - KeyListener 不工作的问题

标签 java keylistener runnable

虽然我已经编码很长一段时间了,但我似乎无法解决我遇到的这个问题(我几乎肯定它是一个我无法捕获的小语法错误,而不是逻辑错误)。我正在制作一个音板,并使用键盘上的数字键盘。我有一个 KeyManager 类:

public class KeyManager implements KeyListener{


private boolean[] keys;
private boolean nine, eight, seven, six, five, four, three, two, one; 

public KeyManager(){
    keys = new boolean [256];
}

public void update(){
    nine = keys[KeyEvent.VK_9];
    eight = keys[KeyEvent.VK_8];
    seven = keys[KeyEvent.VK_7];
    six = keys[KeyEvent.VK_6];
    five = keys[KeyEvent.VK_5];
    four = keys[KeyEvent.VK_4];
    three = keys[KeyEvent.VK_3];
    two = keys[KeyEvent.VK_2];
    one = keys[KeyEvent.VK_1];
}



public void keyPressed(KeyEvent e) {
    keys[e.getKeyCode()] = true;
}

public void keyReleased(KeyEvent e) {
    keys[e.getKeyCode()] = false;
}

public void keyTyped(KeyEvent e) {

}
public boolean isNine() {
    return nine;
}

public boolean isEight() {
    return eight;
}

public boolean isSeven() {
    return seven;
}

public boolean isSix() {
    return six;
}

public boolean isFive() {
    return five;
}

public boolean isFour() {
    return four;
}

public boolean isThree() {
    return three;
}

public boolean isTwo() {
    return two;
}

public boolean isOne() {
    return one;
}
}

这很简单,我使用扩展 JFrame 的 Frame 类作为主 UI 显示:

public class Frame extends JFrame implements Runnable{
private static final long serialVersionUID = 1L;
private Pane pane;
private ArrayList<Circle> c;
private KeyManager keyManager;

public Frame(){
    keyManager = new KeyManager();
    this.addKeyListener(keyManager);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.getContentPane().setPreferredSize(new Dimension(400, 400));
    this.pack();
    this.setLocationRelativeTo(null);
    pane = new Pane();
    this.add(pane);
    c = new ArrayList<Circle>();
    c.add(new Circle(20, 140));
    c.add(new Circle(80, 140));
    c.add(new Circle(140, 140));
    c.add(new Circle(20, 80));
    c.add(new Circle(80, 80));
    c.add(new Circle(140, 80));
    c.add(new Circle(20, 20));
    c.add(new Circle(80, 20));
    c.add(new Circle(140, 20));
    this.setVisible(true);
}

public void init(){
    pane.draw(c);
}

public void update(){
    pane.draw(c);
    keyManager.update();
    if(keyManager.isNine()){
        System.out.println("pressed");
        c.get(8).press();
    }
    else{
        c.get(8).release();
        System.out.println("unpressed");
    }
}


public void run() {

    init();

    int fps = 60;
    double timePerUpdate = 1000000000/fps;
    double delta = 0;
    long now;
    long lastTime= System.nanoTime();
    long timer = 0;
    int updates = 0;

    while(true){
        now = System.nanoTime();
        delta += (now - lastTime) / timePerUpdate;
        timer+= now - lastTime; 
        lastTime = now;

        if(delta >= 1){
            update();
            updates ++;
            delta--;
        }

        if(timer >= 1000000000){
            //System.out.println("Updates and Frames: "+ updates);
            updates = 0;
            timer = 0;
        }

    }
}


}

由于某种原因,当我按下键盘上的“9”时,它不会在 Frame.update() 方法中打印出“按下”,而只会打印出“未按下”。我不知道是什么导致了这个问题。这是我第一次使用 KeyManager 类,而不是让 Frame 完成所有的提升,因为这是很好的编程实践,但从逻辑上讲,它应该可以工作,除非我遗漏了一些东西......

最佳答案

您似乎根本没有注册您的 key 管理器。 JFrame 如何知道它有一个关键监听器?

在 Frame 类的最顶部添加这行代码 this.addKeyListener(new KeyManager());

像这样:

public Frame(){
    this.addKeyListener(new KeyManager()); // New code
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.getContentPane().setPreferredSize(new Dimension(400, 400));

编辑:为了将来的引用,请务必检查 javadoc,因为在这种情况下,答案就在那里:

The listener object created from that class is then registered with a component using the component's addKeyListener method.

Java文档: https://docs.oracle.com/javase/7/docs/api/java/awt/event/KeyListener.html

官方教程中再次提到了addKeyListener:

https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html

编辑评论:

让我们通过向按键事件添加一些代码来调试问题。通过这样做,我们可以发现一些事情。

1)关键事件是否被触发。

2)按下的键码和字符是什么

public void keyPressed(KeyEvent e) {
    System.out.println("The following key was pressed: "+e.getKeyChar());
    System.out.println("With the following key code: "+e.getKeyCode());
    System.out.println("Is that the expected output?");
    keys[e.getKeyCode()] = true;
}

您从我们的新调试代码中得到了正确的输出吗?键码是否正确,字符是否正确?您的其他数字键有用吗?

这里要记住的一件事是数字键盘数字与普通数字键具有不同的键代码。我强烈建议您重新编写代码以使用 e.getKeyChar() 或在 update() 方法中包含小键盘键码,并在正常或正常情况下使用 IF 语句。按下小键盘键并将 boolean 值设置为 true/false。

关于java - KeyListener 不工作的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36925263/

相关文章:

java - 带有突出显示点的 JFreeChart

java - 验证中突出显示行

java - 将动态参数传递给 @MapKey ("${dynamicParam}") (My-Batis)

java - 为什么java不支持重启线程

java - 没有组件的事件监听器

java - 如何在按下按钮时循环播放声音并在释放时停止播放?

java - 在 Java 中,如何在每个线程中运行不同的方法?

java - 在 Java 中使用键盘 "ContextMenu"按钮

java - 修改服务器以允许多个客户端同时连接

java - 为什么Java中的java.lang.Thread类没有被设计者标记为final?