guarrana
guarrana

Reputation: 79

KeyListener issue

I'm trying to implement a simple keylistener to make a graphic of an oval move with the left key arrow. The oval does not move nor even read the key press after testing with system.out.println. Any help would be appreciated.

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

public class Game extends JFrame implements KeyListener{

  int x = 450;
  int y = 600;

  public Game() {
    setTitle("Game");
    setSize(1024, 768);
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
  }

  public void paint(Graphics g) {
    g.setColor(Color.BLACK);
    g.fillOval(x, y, 100, 100); 
  }

  public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
      x = x + 20;
      System.out.println("works");
    }
  }
    public void keyReleased(KeyEvent e) {}
    public void keyTyped(KeyEvent e) {}


  public static void main(String[] args) {
    Game game = new Game();
  }
}

Upvotes: 2

Views: 68

Answers (3)

user3437460
user3437460

Reputation: 17454

The oval does not move nor even read the key press after testing with system.out.println. Any help would be appreciated

As far as I see, you didn't add your listener, hence nothing happens when you press the key.

If you are adding to your current Game class, you can do this:

this.addKeyListener(this);

If you are adding the listener outside the current Game class, then:

gameInstance.addKeyListener(gameInstance);

Other issues with your codes:

  • You may want to use KeyBindings instead of KeyListener.
  • Do not override paint(g). Override paintComponent(g) instead. There is almost no reason for us to override paint(g).
  • Usually we do not create a customized JFrame. You may consider creating a JPanel (be it customized or not) and add it into your JFrame.
  • After adding the JPanel (a container) into your JFrame, you can pack() your frame and it will be able to determine its own preferredSize.

Upvotes: 3

MadProgrammer
MadProgrammer

Reputation: 347184

Let's start with the KeyListener issue. KeyListener is well know for not responding to key inputs, and will only generate KeyEvents when the component is focusable AND has focus.

Instead, you should be using the Key Bindings API

Next, you should avoid overriding paint of top level containers like JFrame, for more information why, have a look at

As a general rule of thumb, you should avoid extending JFrame at all and instead prefer using something like JPanel and override it's paintComponent method.

Also remember, painting in Swing is made up of a series of chained method calls, unless you really, really, really know what you're doing, you should always call the super paint method before performing any cusomt painting.

See Painting in AWT and Swing and Performing Custom Painting for more details

Upvotes: 3

John Bollinger
John Bollinger

Reputation: 180093

You misunderstand the purpose and use of KeyListener. Your class implements that interface, but only implementations that are actually registered on the component that generates an event receive that event. That holds even when the component is itself a listener of the appropriate type. Perhaps, therefore, you want

game.addKeyListener(game);

Note also that you potentially have to deal with threading issues. To be properly synchronized, GUI initialization code generally needs to run on the EDT, as you can accomplish with the help of SwingUtilities.invokeAndWait() or SwingUtilities.invokeLater().

Upvotes: 3

Related Questions