Boyen
Boyen

Reputation: 1549

KeyListener not reacting at all

I've been trying to fix this issue for about 5 hours now, but I just can't figure out why my KeyListener is not reacting at all. It doesn't even seem like it gets to the point where it looks for a keyInput? This is the class it is called in :

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) {
    }

}

And the main class:

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

    }
}

The panel class

/*
 * 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);
    }
}

Upvotes: 1

Views: 174

Answers (3)

syb0rg
syb0rg

Reputation: 8247

Use Key Bindings. Here is a short example to show how to use them:

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

Upvotes: 4

MadProgrammer
MadProgrammer

Reputation: 347204

KeyListeners will only react if the component they are registered to is focusable and has focus. Most Swing top level containers are never likely to receive keyboard focus directly, as they have a JRootPane, which has a contentPane (amongst other things) ontop of it (preventing it from ever been able to receive keyboard focus), ontop of which you've added another component.

This is a common known problem with KeyListeners and the main reason we recommend Key Bindings instead.

On a side not, your custom painting is worrying. You should a void overriding paint and instead use paintComponent. You should also be calling super.paintXxx to ensure that the Graphics context is properly prepared for painting?

See Performing Custom Painting for more details

Upvotes: 1

The keylistener doesn't fire if the component which has the listener does not have focus. As I look in your code it seems that you do not actually add the Player instance to JFrame, therefore it cannot have focus.

I'd suggest you to add it to the JFrame and display the frame using this.setVisible(true); That should do the trick

Upvotes: 0

Related Questions