我一直在尝试解决这个问题大约5个小时,但我无法弄清楚为什么我的KeyListener根本没有做出反应。它甚至看起来没有达到它寻找keyInput的程度? 这是它所称的类:
package summonit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
public class Player extends KleinerScreen implements KeyListener {
public Player() throws IOException{
addKeyListener(this);
}
public static int playerX=20;
public static int playerY;
@Override
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_K) {
playerX += 100;
}
System.out.println(playerX);
repaint();
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_K) {
playerX += 100;
}
System.out.println(playerX);
repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
}
主要课程:
package summonit;
import java.awt.*;
import java.io.IOException;
import javax.swing.JFrame;
public class Summonit extends JFrame{
public static void main(String[] args) throws IOException {
Summonit game = new Summonit();
Screen window = new Screen();
TileMap tilemap = new TileMap();
Player player = new Player();
}
}
小组类
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package summonit;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
/**
*
* @author Boyen
*/
public class KleinerScreen extends JPanel {
String i = "457528_3569247037775_1427420686_o.jpg";
String s = "City.txt";
public static Dimension windowsize = new Dimension(1000, 1000);
private int mapWidth;
private int mapHeight;
public int map[][];
final int playerRows = 4;
final int playerCols = 4;
//images of tiles
private Image tileYellowPath;
private Image tileGround;
BufferedImage bigPlayerImg;
BufferedImage[] sprites;
//images
public KleinerScreen() throws IOException {
setPreferredSize(windowsize);
tileYellowPath = new ImageIcon(getClass().getResource("/CorrodedTechnoTiles.png")).getImage();
tileGround = new ImageIcon(getClass().getResource("/images.jpg")).getImage();
bigPlayerImg = ImageIO.read(new File("res/sprites_player_3.png"));
sprites = new BufferedImage[playerRows * playerCols];
for (int i = 0; i < playerRows; i++) {
for (int j = 0; j < playerCols; j++) {
sprites[(i * playerCols) + j] = bigPlayerImg.getSubimage(
j * 150,
i * 150,
150,
150);
}
}
}
public void readTiles() {
}
public void paint(Graphics g) {
for (int i = 0; i < TileMap.map.length; i++) {
for (int j = 0; j < TileMap.map[i].length; j++) {
switch (TileMap.map[i][j]) {
case 0:
g.drawImage(tileGround, windowsize.width / 10 * j, windowsize.height / 10 * i, windowsize.height / 10, windowsize.width / 10, null);
break;
case 1:
g.drawImage(tileYellowPath, windowsize.width / 10 * j, windowsize.height / 10 * i, windowsize.height / 10, windowsize.width / 10, null);
break;
}
}
}
g.drawImage(sprites[5], Player.playerX, 0 ,100,100,null);
}
}
答案 0 :(得分:4)
使用Key Bindings。这是一个简短的例子来说明如何使用它们:
public class Test
{
JFrame frame = new JFrame();
public Test()
{
ActionMap actionMap = frame.getRootPane().getActionMap();
InputMap inputMap = frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
for (Keys direction : Keys.values())
{
actionMap.put(direction.getText(), new KeyBinding(direction.getText()));
inputMap.put(direction.getKeyStroke(), direction.getText());
}
frame.getRootPane().setActionMap(actionMap);
frame.getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
frame.setVisible(true);
}
private class KeyBinding extends AbstractAction
{
private static final long serialVersionUID = 1L;
public KeyBinding(String text)
{
super(text);
putValue(ACTION_COMMAND_KEY, text);
}
@Override
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
System.out.println("Key Binding: " + action);
}
}
public static void main(String... args)
{
new Test();
}
}
enum Keys
{
ESCAPE("Escape", KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)),
CTRLC("Control-C", KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK)),
CTRLP("Control-P", KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.CTRL_DOWN_MASK)),
UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)),
DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)),
LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)),
RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
private String text;
private KeyStroke keyStroke;
Keys(String text, KeyStroke keyStroke)
{
this.text = text;
this.keyStroke = keyStroke;
}
public String getText()
{
return text;
}
public KeyStroke getKeyStroke()
{
return keyStroke;
}
@Override
public String toString()
{
return text;
}
}
答案 1 :(得分:1)
KeyListeners
只会在他们注册的组件具有焦点并且具有焦点时才会做出反应。大多数Swing顶级容器永远不会直接接收键盘焦点,因为它们有一个JRootPane
,其上面有一个contentPane(以及其他东西)(防止它无法接收键盘焦点),ontop其中你添加了另一个组件。
这是[{1}}常见的已知问题,也是我们推荐Key Bindings的主要原因。
不在一边,你的自定义绘画令人担忧。你应该覆盖空白,而是使用KeyListeners
。您还应该调用paintComponent
以确保super.paintXxx
上下文已准备好进行绘画?
有关详细信息,请参阅Performing Custom Painting
答案 2 :(得分:0)
如果具有侦听器的组件没有焦点,则不会触发keylistener。当我查看你的代码时,似乎你实际上没有将Player实例添加到JFrame,因此它无法获得焦点。
我建议您将其添加到JFrame并使用this.setVisible(true);
显示框架
那应该是诀窍