KeyListener根本没有反应

时间:2013-05-05 20:40:00

标签: java swing jpanel keylistener

我一直在尝试解决这个问题大约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);
    }
}

3 个答案:

答案 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);显示框架 那应该是诀窍