如何在Java中使用KeyEvents Listener来监听KeyPressed事件。

huangapple go评论82阅读模式
英文:

How to use KeyEvents Listener in Java for KeyPressed

问题

Window

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.getKeyCode() == KeyEvent.VK_LEFT) {
        panel.LeftKey();
    };

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

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

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

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

KeyPanel

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

这是你的整个程序。如果有任何帮助,谢谢!

英文:

I am a newbie to Java and I have been working on a landmine game. I finished the board and the key events but the key events are not working. I am not sure what I am doing wrong. I have shown the code below. I used some help from Youtube from the following video: https://www.youtube.com/watch?v=7kMXr2AJLPA

Window

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(&quot;Landmine Game!&quot;);
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) {
}
}

KeyPanel

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 &lt; board.length; row++) {
for (int col = 0; col &lt; 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();
}
}

This is my whole program. Any help is appreciated, thank you!

答案1

得分: 2

使用KeyListenerJPanel是行不通的。你将不得不改用KeyBindings。例如:

panel.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
panel.getActionMap().put("left", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按下了左键");
}
});

然而,这些匿名的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方法放在一个继承自Canvas的类中。这是完全没有意义的。

英文:

Using a KeyListener to a JPanel is not going to work. You will have to use KeyBindings instead. For example:

panel.getInputMap().put(KeyStroke.getKeyStroke(&quot;LEFT&quot;), &quot;left&quot;);
panel.getActionMap().put(&quot;left&quot;, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(&quot;left key is pressed&quot;);
}
});

However, these anonymous AbstractAction classes annoy me. That's why I would do something like that:

public class RunnableAction extends AbstractAction {
private Runnable action;
public RunnableAction(Runnable action) {
this.action = action;
}
@Override
public void actionPerformed(ActionEvent e) {
action.run();
}
}

And then:

panel.getInputMap().put(KeyStroke.getKeyStroke(&quot;LEFT&quot;), &quot;left&quot;);
panel.getActionMap().put(&quot;left&quot;, new RunnableAction(panel::LeftKey));
panel.getInputMap().put(KeyStroke.getKeyStroke(&quot;RIGHT&quot;), &quot;right&quot;);
panel.getActionMap().put(&quot;right&quot;, new RunnableAction(panel::RightKey));
panel.getInputMap().put(KeyStroke.getKeyStroke(&quot;DOWN&quot;), &quot;down&quot;);
panel.getActionMap().put(&quot;down&quot;, new RunnableAction(panel::DownKey));
panel.getInputMap().put(KeyStroke.getKeyStroke(&quot;UP&quot;), &quot;up&quot;);
panel.getActionMap().put(&quot;up&quot;, new RunnableAction(panel::UpKey));

However, I suggest you to try following the standard naming conventions. For example, methods should start with lower case. (panel.UpKey() should be panel.upKey(), etc)

Finally you do not have to have your main method in a class that extends Canvas. This is totally pointless.

huangapple
  • 本文由 发表于 2020年8月21日 17:10:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/63519881.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定