Search code examples
javaswingjpanelkey-bindings

How to move Key Binding method into its own Class?


I am making a game and have got keybindings working in my GamePanel class. However I want to be able to put my key bindings method in its own separate class, so that other panels of the game can access the method, so I don't have to rewrite it each time. I've moved it over as you can see, but I am getting a null pointer exception on the line that calls the addKeyBinding method. I'm thinking this has something to do with it not knowing what action to call? But I'm not sure. How can I fix this?

GamePanel class:


public class GamePanel extends JPanel implements ActionListener {
    // Global Variables
    private Ball ball;
    private Paddle paddle;
    private GameFrame gameFrame;
    private int width;
    private int height; 
    private Timer timer;
    private int brickHeight = 30;
    private int brickWidth = 60;
    ArrayList<Bricks> brickArray = new ArrayList<Bricks>();
    int brickCount;
    int leftOverSpace;
    private int ballXDir = -1;
    private int ballYDir = -2;
    private boolean play = false;
    private int delay = 8;
    private KeyBindings kBindings;

    // create a constructor
    GamePanel (int gamePanelWidth, int gamePanelHeight) {
        this.setWidth(gamePanelWidth);
        this.setHeight(gamePanelHeight);
        initialiseGame();
        this.isVisible();
    }

    private void initialiseGame() {
        play = false;
        ball = new Ball(10, 520, 30, 30, this); //create the ball object
        paddle = new Paddle(this, 50, 700, 100, 10); //creates paddle object
        initialiseBrickArray();
        
        //initialise key bindings for space, left and right
        kBindings.addKeyBinding(this, KeyEvent.VK_SPACE, "startBall", (evt) -> {
            play = true;
        });
        kBindings.addKeyBinding(this, KeyEvent.VK_LEFT, "moveLeft", (evt) -> {
            paddle.moveLeft();
        });
        kBindings.addKeyBinding(this, KeyEvent.VK_RIGHT, "moveRight", (evt) -> {
            paddle.moveRight();
        });       
    }
 
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
    }  
}

My new KeyBindings class:

public class KeyBindings implements ActionListener {

    public void addKeyBinding(JComponent comp, int keyCode, String id, ActionListener actionListener) {
        InputMap im = comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap ap = comp.getActionMap();

        im.put(KeyStroke.getKeyStroke(keyCode, 0, false), id);
        ap.put(id, new AbstractAction() {

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

        return;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub

    }
    
}

Solution

  • You should initialize kBindings in constructor, or somewhere else, but before you call kBindings.addKeyBinding. Just

    kBindings = new KeyBindings();