首页 > 解决方案 > 如何在 Java 中为 KeyPressed 使用 KeyEvents 侦听器

问题描述

我是 Java 新手,我一直在开发地雷游戏。我完成了董事会和关键事件,但关键事件不起作用。我不确定我做错了什么。我已经展示了下面的代码。我从以下视频中使用了 Youtube 的一些帮助:https ://www.youtube.com/watch?v=7kMXr2AJLPA

窗户

package com.landminegame.main;

import java.awt.*;

import javax.swing.JFrame;

public class Window extends Canvas {

private static final long serialVersionUID = -240840600533728354L;

public static void main (String args[]) {
    JFrame frame = new JFrame("Landmine Game!");
    KeyPanel panel = new KeyPanel();
    panel.setFocusable(true);
    panel.addKeyListener(new KeyPressedKeyListener(panel));
    panel.setOpaque(false);
    frame.setSize(500, 500);
    frame.getContentPane().add(panel);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}
}

KeyPressedKeyListener

package com.landminegame.main;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyPressedKeyListener implements KeyListener {

private KeyPanel panel;

public KeyPressedKeyListener(KeyPanel panel) {
    this.panel = panel;
}

@Override
public void keyTyped(KeyEvent keyEvent) {
}

@Override
public void keyPressed(KeyEvent keyEvent) {
    if (keyEvent.KEY_PRESSED == KeyEvent.VK_LEFT) {
        panel.LeftKey();
    };

    if (keyEvent.KEY_PRESSED == KeyEvent.VK_RIGHT) {
        panel.RightKey();
    };

    if (keyEvent.KEY_PRESSED == KeyEvent.VK_UP) {
        panel.UpKey();
    };

    if (keyEvent.KEY_PRESSED == KeyEvent.VK_DOWN) {
        panel.DownKey();
    };
}

@Override
public void keyReleased(KeyEvent keyEvent) {
}
}

按键面板

package com.landminegame.main;

import javax.swing.*;
import java.awt.*;

public class KeyPanel extends JPanel {

public Rectangle mover = new Rectangle(56, 305, 40, 40);

private int [][] board = {
        {1, 1, 1, 1, 1, 1, 1, 1},
        {1, 0, 3, 3, 0, 3, 4, 1},
        {1, 0, 3, 3, 3, 0, 3, 1},
        {1, 3, 3, 0, 3, 3, 0, 1},
        {1, 0, 3, 0, 3, 0, 0, 1},
        {1, 3, 0, 3, 0, 0, 0, 1},
        {1, 2, 3, 0, 3, 0, 0, 1},
        {1, 1, 1, 1, 1, 1, 1, 1}
};

public void paint(Graphics g) {
    super.paint(g);
    g.translate(28, 25);

    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[0].length; col++) {
            Color color = Color.WHITE;
            switch (board[row][col]) {
                case 1 : color = Color.BLACK; break;
                case 2 : color = Color.YELLOW; break;
                case 4 : color = Color.RED;
            }
            g.setColor(color);
            g.fillRect(50*col, 50 * row, 50, 50);
            g.setColor(Color.BLACK);
            g.drawRect(50*col, 50*row, 50, 50);
        }
    }

    g.setColor(Color.GREEN);
    g.fillRect(mover.x, mover.y, mover.width, mover.height);
}

public void LeftKey() {
    mover.x -= 40;
    this.repaint();
}

public void RightKey() {
    mover.x += 40;
    this.repaint();
}

public void UpKey() {
    mover.y += 40;
    this.repaint();
}

public void DownKey() {
    mover.y -= 40;
    this.repaint();
}
}

这是我的整个程序。任何帮助表示赞赏,谢谢!

标签: javaswingawt

解决方案


使用 a KeyListenerto aJPanel是行不通的。您将不得不改用 KeyBindings。例如:

panel.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
panel.getActionMap().put("left", new AbstractAction() {

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("left key is pressed");
    }
});

但是,这些匿名AbstractAction课程让我很恼火。这就是为什么我会做这样的事情:

public class RunnableAction extends AbstractAction {

    private Runnable action;

    public RunnableAction(Runnable action) {
        this.action = action;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        action.run();
    }
}

进而:

panel.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
panel.getActionMap().put("left", new RunnableAction(panel::LeftKey));

panel.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right");
panel.getActionMap().put("right", new RunnableAction(panel::RightKey));

panel.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down");
panel.getActionMap().put("down", new RunnableAction(panel::DownKey));

panel.getInputMap().put(KeyStroke.getKeyStroke("UP"), "up");
panel.getActionMap().put("up", new RunnableAction(panel::UpKey));

但是,我建议您尝试遵循标准命名约定。例如,方法应该以小写字母开头。(panel.UpKey()应该是panel.upKey()等)

最后,您不必将您的main方法放在一个类中extends Canvas。这是完全没有意义的。


推荐阅读