2

If you use the java KeyListener class you know that if you hold down a key keyPressed will fire one KeyEvent, and then about half a second later will fire the same key many times very very fast. I would like to know if there is a way to keep the KeyEvents from firing too fast. I would like them to be at a nice constant rate of about once every 500 ms.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Mark
  • 21
  • 1
  • 1
  • 2

4 Answers4

6

You can, but the trick is to not slow down the firing of events, but to slow down how fast you process them:

KeyListener kl = new KeyListener() {
    private long lastPressProcessed = 0;

    @Override
    public void keyPressed(KeyEvent e) {
        if(System.currentTimeMillis() - lastPressProcessed > 500) {
            //Do your work here...
            lastPressProcessed = System.currentTimeMillis();
        }           
    }

    @Override
    public void keyTyped(KeyEvent e) {}

    @Override
    public void keyReleased(KeyEvent e) {   }

};
  • This will only work well if the system key-repeat is very rapid. If it is, say, 400 ms between presses, then this may cause delays on up to 900 ms. – aioobe Mar 04 '11 at 21:48
  • @aioobe - There's no way around that, I think, other than changing the system autorepeat rate. It's a property of undersampling; there's going to be aliasing, which will appear as a jittery repeat time. If you are processing long streams of autorepeat events, then one can apply antialiasing techniques to reduce the jitter, but I doubt that long streams of autorepeat events are a common application. – Ted Hopp Mar 06 '11 at 00:19
3

No, this is completely system dependent. You would have to listen for keyPressed events, start a timer on your own that fires events at a fixed rate and stop it at the next keyReleased event.

Try something like this:

component.addKeyListener(new KeyListener() {

    Timer t = new Timer();
    TimerTask tt;

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
        tt.cancel();
        tt = null;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (tt != null)
            return;

        tt = new TimerTask() {
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis() % 1000);
            }
        };

        t.scheduleAtFixedRate(tt, 0, 500);
    }
});
aioobe
  • 413,195
  • 112
  • 811
  • 826
2

This is controlled by your OS. But you could easily have your handler check how long it is since the last time it fired and respond accordingly.

Matthew Gilliard
  • 9,298
  • 3
  • 33
  • 48
1

Usually the auto-repeat rate for keys is set by the system; I don't know if it's changeable from within Java. However, you can use the event arrival time to not react to one until 500ms after the last time you reacted (or after a key release, which should clear the timer for users who type fast).

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521