Yes, it’s really annoying :’(
This is what I do now:
public class Game implements KeyListener
{
private class Keyvent
{
public KeyEvent _event;
public boolean _pressed;
public Keyvent(KeyEvent event, boolean pressed)
{
_event = event;
_pressed = pressed;
}
}
private Queue<Keyvent> _keyvents;
public Game()
{
_keyvents = new LinkedList<Keyvent>();
}
public void keyPressed(KeyEvent e)
{
_keyvents.add(new Keyvent(e, true));
}
public void keyReleased(KeyEvent e)
{
_keyvents.add(new Keyvent(e, false));
}
public void update()
{
if (!_keyvents.isEmpty())
{
Iterator<Keyvent> it = _keyvents.iterator();
Keyvent a = it.next();
while (it.hasNext())
{
Keyvent b = it.next();
if (a._event.getKeyCode() == b._event.getKeyCode()
&& !a._pressed && b._pressed
&& a._event.getWhen() == b._event.getWhen())
{
if (it.hasNext())
{
a = it.next();
}
else
{
a = null;
}
}
else
{
processKeyvent(a);
a = b;
}
}
if (a != null)
{
processKeyvent(a);
}
_keyvents.clear();
}
}
private void processKeyvent(Keyvent keyvent)
{
if (keyvent._pressed)
{
// do something with pressed key
}
else
{
// do something with released key
}
}
}
The problem is that update() does not run in the same thread as keyPressed and keyReleased. Sometimes update() gets invoked after the “fake” keyReleased has been put into the Queue, but the corresponding “fake” keyPressed has not yet been, and so the fake pair is not recognised as such.
Is there really no simple way such as a method like disableKeyRepeat() or something? :’(