0

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!

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Hi there! Thank you for your response. Unfortunately, when I add the panel.getInputMap().put code, it says that it cannot resolve the symobls getInputMap and getActionMap. I looked at the website for key bindings and it mentions that I have to add these parameters for InputMap and ActionMap. However, I am not sure how. Is there a website that can help me figure this out? Sorry for this, just a bit new to KeyBindings.
@SyedAlam, When you learn a new concept, start with something simple. So forget about your application. Instead create a JFrame with a JPanel and attempt to add the Key Bindings to the panel and simple display a message when a specific key is pressed. If it doesn't work then you have a proper minimal reproducible example to post and we can help you out. We can't guess why you would get a compile error if we can't see your code. There is no trick to using those methods. If it does work, then you use the knowledge learned an apply it to your real app.
@SyedAlam, Also note that method names should NOT start with an upper case character.
@camickr Ok, thank you! I shall try that out and see if I can get the hand of it. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.