Saturday, June 20, 2009

Key Repetition with TimerTask

It is not friendly to force your user to repeat key presses. My CustomImplicitList had this fault. If you wanted to move the selection using up/down keys or 2/8 numbers you had to press the key once for every change. To avoid this I made a simple change, adding the following method:

protected void keyRepeated(int keyCode) {
this.keyPressed(keyCode);
}

Now the user can press and hold a key to keep changing the selection, right? Wrong! Because not all Java ME Virtual Machines call keyRepeated. You can know it by calling Canvas.hasRepeatEvents(). So, how do we grant key repetition to these devices?

I could use a Thread and flag attributes to solve this problem, but I prefer creating an inner class at CustomImplicitList:

class KeyRepeatTask extends TimerTask {
public void run() {
if (isShown() && keyCode != Integer.MIN_VALUE) {
keyPressed(keyCode);
}
}
}

Two new attributes will help me control the key repetition:

private Timer keyRepeatTimer;
private int keyCode = Integer.MIN_VALUE;

To start the key repetition I added the following lines to the very start of keyPressed method:

if (this.hasRepeatEvents() == false && this.keyCode == Integer.MIN_VALUE) {
this.keyCode = keyCode;
this.keyRepeatTimer = new Timer();
// keep repeating the task at each 700 milliseconds
this.keyRepeatTimer.scheduleAtFixedRate(new KeyRepeatTask(), new Date(), 700);
}

To stop the key repetition I added the following method:

protected void keyReleased(int keyCode) {
if (this.keyRepeatTimer != null) {
this.keyCode = Integer.MIN_VALUE;
this.keyRepeatTimer.cancel();
this.keyRepeatTimer = null;
}
}

How did I test this? First I removed the implementation of keyRepeated and added hasRepeatEvents always returning false. Then I executed my use case on emulators and personal handsets. Of course this is not enough to guarantee the same behavior on all Java ME enabled handsets, as this is highly dependendent on the correct implementation of hasRepeatEvents but is a safe start.

If you find out this code does not work on your handset, please let me know.

Related topics:

No comments: