Reputation: 79
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
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:
paint(g)
. Override paintComponent(g)
instead. There is almost no reason for us to override paint(g)
.JFrame
. You may consider creating a JPanel
(be it customized or not) and add it into your JFrame.pack()
your frame and it will be able to determine its own preferredSize
.Upvotes: 3
Reputation: 347184
Let's start with the KeyListener
issue. KeyListener
is well know for not responding to key inputs, and will only generate KeyEvent
s 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
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