user1852433
user1852433

Reputation: 13

KeyListener won't work even though panel prints

I have the following code (I do frame.add(new LevelPanel()) in my main method that extends JFrame. For some reason, this code for the KeyListener is exactly how it is for other people and yet it doesn't recognize anything.

It should at least print out "Got here" when I press a key (and it doesn't). The code does print the panel, but the panel has no reaction to any of the keys I press.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/*
 * Items represent the things in the level that can be picked up.
 * Subclasses: Gem
 * 
 * @author Tim Ochsner
 * @version 1.0 11/18/2012
 */

public class LevelPanel extends JPanel {
private Game game;
private Level level;
private Player player;
private char[][] table =
        {{'p', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f'},
        {'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f', 'f', 'f'},
        {'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f', 'f', 'f'},
        {'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f', 'w', 'w', 'w', 'f', 'f', 'f', 'f'},
        {'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f'},
        {'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f'},
        {'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f'},
        {'w', 'f', 'f', 'f', 'w', 'w', 'w', 'w', 'w', 'f', 'f', 'f', 'f', 'f', 'f'},
        {'w', 'w', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'w', 'f'},
        {'w', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'w', 'f'},
        {'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'w', 'f'},
        {'f', 'f', 'f', 'f', 'f', 'f', 'w', 'w', 'w', 'w', 'f', 'f', 'w', 'w', 'f'},
        {'f', 'f', 'w', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'w', 'f', 'f', 'w', 'f'},
        {'f', 'f', 'w', 'f', 'f', 'f', 'f', 'f', 'f', 'w', 'f', 'f', 'f', 'f', 'f'},
        {'w', 'w', 'w', 'w', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f', 'f'}};

public LevelPanel(Game game)
{
    this.game = game;
    player = game.getPlayer();
    level = new Level(game, table);
    setBackground(Color.WHITE);
    addKeyListener(new ArrowListener());

}

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    level.draw(g);
}

public class ArrowListener implements KeyListener {

    public void keyPressed(KeyEvent e) {
        System.out.println("Got here");
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            if (!(player.getCol() == 14) && level.getTileLayout()[player.getRow() + 1][player.getCol()].isPassable()) {
                System.out.println("Got here");
                player.move(player.getRow() + 1, player.getCol());
                table[player.getRow()][player.getCol()] = 'f';
                table[player.getRow() + 1][player.getCol()] = 'p';
            }
        }

    }

    public void keyReleased(KeyEvent e) {
        System.out.println("Got here");

    }

    public void keyTyped(KeyEvent arg0) {
            System.out.println("Got here");         
    }

}

}

Upvotes: 1

Views: 425

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

KeyListener is a fickle mistress, I would recommend that you avoid them in favor of key bindings

KeyListener will only fire an event if 1- The component is focusable and 2- the component has focus. Key bindings allow you to get around this restriction.

If you MUST use a KeyListener, first call setFocusable(true) on your LevelPanel, followed by requestFocusInWindow.

Upvotes: 1

Related Questions