Okay, so I’m pretty frustrated here.
This piece of code here is just a very simple moving JComponent.
What’s odd is how, when I’m changing absolutely nothing, the keyPressed event will be incredibly inconsistent. I start the program, and sometimes it’ll work, and my ball will move around the screen. On the other hand, I’ll close it and open it without changing anything, and it’ll fail to work. I don’t think focus is a problem here, though I really don’t know much about it. I have no idea what’s going on.
Any help would be appreciated. I just don’t see how the program could so inconsistently fail and succeed.
And here’s my code in the character’s class, because I don’t think just giving you a snippet will help. I don’t know if it’s just me, or whatever, but if you want to compile it and see, go ahead.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Character extends JComponent implements KeyListener
{
Timer timer = new Timer(5, new TimeListener());
private int x = 250;
private int y = 300;
char whichTimer;
public Character()
{
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
repaint();
}
public void keyReleased(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_W)
{
timer.stop();
}
if(e.getKeyCode() == KeyEvent.VK_A)
{
timer.stop();
}
if(e.getKeyCode() == KeyEvent.VK_S)
{
timer.stop();
}
if(e.getKeyCode() == KeyEvent.VK_D)
{
timer.stop();
}
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_W)
{
timer.stop();
whichTimer = 'W';
timer.start();
}
if(e.getKeyCode() == KeyEvent.VK_A)
{
timer.stop();
whichTimer = 'A';
timer.start();
}
if(e.getKeyCode() == KeyEvent.VK_S)
{
timer.stop();
whichTimer = 'S';
timer.start();
}
if(e.getKeyCode() == KeyEvent.VK_D)
{
timer.stop();
whichTimer = 'D';
timer.start();
}
}
public void keyTyped(KeyEvent e)
{
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// g2d.drawImage(fatsprite, x-10, y-10, null);
g.setColor(Color.BLACK);
g.fillOval(x-10, y-10, 20, 20);
}
class TimeListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(whichTimer == 'W')
{
y-=1;
repaint();
}
if(whichTimer == 'A')
{
x-=1;
repaint();
}
if(whichTimer == 'S')
{
y+=1;
repaint();
}
if(whichTimer == 'D')
{
x+=1;
repaint();
}
}
}
}
@Max is correct,
KeyBindingsis better approach to your problem. The key problem (sorry, no pun intended) is that once focus moves to any other component, you will no longer receive key events. Now, you’re probably thinking, “but I didn’t change focus” – you only need to click on another focusable component to loss key focus, or press tab, whichKeyListenerwon’t generally be notified of.Generally, as you’ve found,
KeyListenersare unreliable, not only are they only ever going to get notification while the component in question has focus, keys can be consumed before they reach you