Giani Noyez
Giani Noyez

Reputation: 491

addKeylistener() not working

For school I have to make a small game which is based on Breakout.

I got my JFrame which does this:

game.setFocusable(true);
setContentpane(game);

in my game I am adding a inputhandler which extends Keylistener and implements JPanel.

setFocusable(true);
Inputhandler input = new Inputhandler();
addKeylistener(input);

It just doesn't seem to work, I've been writing a lot of tests but I can't see to get the input handle capture any keyPressed.

When I change my JFrame to:

add(game);

it works like it is meant to work but the problem I encounter when doing this way is painting my panels the correct way. I'm kinda stuck on this issue so please someone help me out.

Point I've reached now:

public Game(){
    setFocusable(true);
    requestFocus();
    requestFocusInWindow();

    getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressed");
    getActionMap().put("pressed", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Space is pressed");
        }
    });

    this.inputHandler = new InputHandler();
    addKeyListener(this.inputHandler);

    setPreferredSize(new Dimension(500,500));
}

Upvotes: 1

Views: 6908

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

If I had a dollar for every time this question were asked, I'd retire rich. As per previous similar questions...

  • Yes you would need to make the JPanel focusable for its KeyListener to work
  • And you'd also have to give it the focus, since being focusable is not enough. Usually this is achieved by calling requestFocusInWindow() on the listened to JPanel.
  • And nothing else can have the focus or steal the focus if the KeyListener is to continue functioning.
  • Which is one of several reasons why most of us recommend against use of KeyListeners for Swing applications
  • And usually in favor of using Key Bindings.

Edit

I've used your code and it works, both the key bindings and the KeyListener:

import java.awt.Dimension;
import java.awt.event.*;

import javax.swing.*;

public class Game extends JPanel {
   private InputHandler inputHandler;

   public Game() {
      setFocusable(true);
      requestFocus();
      requestFocusInWindow();
      getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressed");
      getActionMap().put("pressed", new AbstractAction() {
         @Override
         public void actionPerformed(ActionEvent e) {
            System.out.println("Space is pressed");
         }
      });
      this.inputHandler = new InputHandler();
      addKeyListener(this.inputHandler);
      setPreferredSize(new Dimension(500, 500));
   }

   class InputHandler extends KeyAdapter {
      @Override
      public void keyPressed(KeyEvent e) {
         System.out.println("key pressed");
      }

      @Override
      public void keyReleased(KeyEvent e) {
         System.out.println("key released");
      }
   }

   private static void createAndShowGui() {
      Game mainPanel = new Game();

      JFrame frame = new JFrame("Game");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Upvotes: 3

Related Questions