Reputation: 1549
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
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
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
Reputation: 1218
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