Syed Alam
Syed Alam

Reputation: 13

How to use KeyEvents Listener in Java for KeyPressed

I am a newbie to Java and I have been working on a landmine game. I finished the board and the key events but the key events are not working. I am not sure what I am doing wrong. I have shown the code below. I used some help from Youtube from the following video: https://www.youtube.com/watch?v=7kMXr2AJLPA

Window

package com.landminegame.main;

import java.awt.*;

import javax.swing.JFrame;

public class Window extends Canvas {

private static final long serialVersionUID = -240840600533728354L;

public static void main (String args[]) {
    JFrame frame = new JFrame("Landmine Game!");
    KeyPanel panel = new KeyPanel();
    panel.setFocusable(true);
    panel.addKeyListener(new KeyPressedKeyListener(panel));
    panel.setOpaque(false);
    frame.setSize(500, 500);
    frame.getContentPane().add(panel);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}
}

KeyPressedKeyListener

package com.landminegame.main;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyPressedKeyListener implements KeyListener {

private KeyPanel panel;

public KeyPressedKeyListener(KeyPanel panel) {
    this.panel = panel;
}

@Override
public void keyTyped(KeyEvent keyEvent) {
}

@Override
public void keyPressed(KeyEvent keyEvent) {
    if (keyEvent.KEY_PRESSED == KeyEvent.VK_LEFT) {
        panel.LeftKey();
    };

    if (keyEvent.KEY_PRESSED == KeyEvent.VK_RIGHT) {
        panel.RightKey();
    };

    if (keyEvent.KEY_PRESSED == KeyEvent.VK_UP) {
        panel.UpKey();
    };

    if (keyEvent.KEY_PRESSED == KeyEvent.VK_DOWN) {
        panel.DownKey();
    };
}

@Override
public void keyReleased(KeyEvent keyEvent) {
}
}

KeyPanel

package com.landminegame.main;

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

public class KeyPanel extends JPanel {

public Rectangle mover = new Rectangle(56, 305, 40, 40);

private int [][] board = {
        {1, 1, 1, 1, 1, 1, 1, 1},
        {1, 0, 3, 3, 0, 3, 4, 1},
        {1, 0, 3, 3, 3, 0, 3, 1},
        {1, 3, 3, 0, 3, 3, 0, 1},
        {1, 0, 3, 0, 3, 0, 0, 1},
        {1, 3, 0, 3, 0, 0, 0, 1},
        {1, 2, 3, 0, 3, 0, 0, 1},
        {1, 1, 1, 1, 1, 1, 1, 1}
};

public void paint(Graphics g) {
    super.paint(g);
    g.translate(28, 25);

    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[0].length; col++) {
            Color color = Color.WHITE;
            switch (board[row][col]) {
                case 1 : color = Color.BLACK; break;
                case 2 : color = Color.YELLOW; break;
                case 4 : color = Color.RED;
            }
            g.setColor(color);
            g.fillRect(50*col, 50 * row, 50, 50);
            g.setColor(Color.BLACK);
            g.drawRect(50*col, 50*row, 50, 50);
        }
    }

    g.setColor(Color.GREEN);
    g.fillRect(mover.x, mover.y, mover.width, mover.height);
}

public void LeftKey() {
    mover.x -= 40;
    this.repaint();
}

public void RightKey() {
    mover.x += 40;
    this.repaint();
}

public void UpKey() {
    mover.y += 40;
    this.repaint();
}

public void DownKey() {
    mover.y -= 40;
    this.repaint();
}
}

This is my whole program. Any help is appreciated, thank you!

Upvotes: 0

Views: 363

Answers (1)

George Z.
George Z.

Reputation: 6808

Using a KeyListener to a JPanel is not going to work. You will have to use KeyBindings instead. For example:

panel.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
panel.getActionMap().put("left", new AbstractAction() {

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("left key is pressed");
    }
});

However, these anonymous AbstractAction classes annoy me. That's why I would do something like that:

public class RunnableAction extends AbstractAction {

    private Runnable action;

    public RunnableAction(Runnable action) {
        this.action = action;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        action.run();
    }
}

And then:

panel.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
panel.getActionMap().put("left", new RunnableAction(panel::LeftKey));

panel.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right");
panel.getActionMap().put("right", new RunnableAction(panel::RightKey));

panel.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down");
panel.getActionMap().put("down", new RunnableAction(panel::DownKey));

panel.getInputMap().put(KeyStroke.getKeyStroke("UP"), "up");
panel.getActionMap().put("up", new RunnableAction(panel::UpKey));

However, I suggest you to try following the standard naming conventions. For example, methods should start with lower case. (panel.UpKey() should be panel.upKey(), etc)

Finally you do not have to have your main method in a class that extends Canvas. This is totally pointless.

Upvotes: 2

Related Questions