(Edited for clarity)
I want to detect when a user presses and releases a key in Java Swing, ignoring the keyboard auto repeat feature. I also would like a pure Java approach the works on Linux, Mac OS and Windows.
Requirements:
- When the user presses some key I want to know what key is that;
- When the user releases some key, I want to know what key is that;
- I want to ignore the system auto repeat options: I want to receive just one keypress event for each key press and just one key release event for each key release;
- If possible, I would use items 1 to 3 to know if the user is holding more than one key at a time (i.e, she hits 'a' and without releasing it, she hits "Enter").
The problem I'm facing in Java is that under Linux, when the user holds some key, there are many keyPress and keyRelease events being fired (because of the keyboard repeat feature).
I've tried some approaches with no success:
- Get the last time a key event occurred - in Linux, they seem to be zero for key repeat, however, in Mac OS they are not;
- Consider an event only if the current keyCode is different from the last one - this way the user can't hit twice the same key in a row;
Here is the basic (non working) part of code:
import java.awt.event.KeyListener;
public class Example implements KeyListener {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
System.out.println("KeyPressed: "+e.getKeyCode()+", ts="+e.getWhen());
}
public void keyReleased(KeyEvent e) {
System.out.println("KeyReleased: "+e.getKeyCode()+", ts="+e.getWhen());
}
}
When a user holds a key (i.e, 'p') the system shows:
KeyPressed: 80, ts=1253637271673
KeyReleased: 80, ts=1253637271923
KeyPressed: 80, ts=1253637271923
KeyReleased: 80, ts=1253637271956
KeyPressed: 80, ts=1253637271956
KeyReleased: 80, ts=1253637271990
KeyPressed: 80, ts=1253637271990
KeyReleased: 80, ts=1253637272023
KeyPressed: 80, ts=1253637272023
...
At least under Linux, the JVM keeps resending all the key events when a key is being hold. To make things more difficult, on my system (Kubuntu 9.04 Core 2 Duo) the timestamps keep changing. The JVM sends a key new release and new key press with the same timestamp. This makes it hard to know when a key is really released.
Any ideas?
Thanks