英文:
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("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) {
}
}
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();
}
}
This is my whole program. Any help is appreciated, thank you!
答案1
得分: 2
使用KeyListener到JPanel是行不通的。你将不得不改用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("LEFT"), "left");
panel.getActionMap().put("left", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("left key is pressed");
}
});
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("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));
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论