j2me的Canvas中有一个repeat()回调方法。大部分手机支持这个方法,但也有一些手机不支持。在支持的手机中,也存在或多或少的问题,比如在 S40 手机中,repeat()间隔时间过长,导致程序反应太慢。在一个地图浏览的程序中,如果我想连续移动地图, repeat() 几乎是每隔 1 秒执行一次,地图跳跃感太强了。
所以我就想利用keyPressed()和keyReleased()自定义一个repeat()方法,代码如下,这个应用可以自己控制repeat的时间间隔长短,非常好用。
public class RepeatCanvas extends Canvas {
private boolean isRightPressed, isLeftPressed, isDownPressed, isUpPressed;
private Object lock = new Object();
private Thread keyOpt;
protected void paint(Graphics g) {
}
protected void keyPressed(int keyCode) {
int action = getGameAction(keyCode);
switch (action) {
case Canvas.RIGHT:
isRightPressed = true;
break;
case Canvas.LEFT:
isLeftPressed = true;
break;
case Canvas.DOWN:
isDownPressed = true;
break;
case Canvas.UP:
isUpPressed = true;
break;
}
opt();
}
protected void keyReleased(int keyCode) {
int action = getGameAction(keyCode);
switch (action) {
case Canvas.RIGHT:
isRightPressed = false;
break;
case Canvas.LEFT:
isLeftPressed = false;
break;
case Canvas.DOWN:
isDownPressed = false;
break;
case Canvas.UP:
isUpPressed = false;
break;
}
}
private void opt() {
if (keyOpt != null) {
synchronized (lock) {
lock.notify();
}
} else {
keyOpt = new Thread(new KeyOpt());
keyOpt.start();
}
}
private class KeyOpt implements Runnable {
public void run() {
while (true) {
if (isRightPressed) {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
break;
}
System.out.println("move(-1, 'x') -- 地图右移");
if (!isRightPressed) {
break;
}
}
} else if (isLeftPressed) {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
break;
}
System.out.println("move(1, 'x') -- 地图左移");
if (!isLeftPressed) {
break;
}
}
} else if (isDownPressed) {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
break;
}
System.out.println("move(-1, 'y') -- 地图下移");
if (!isDownPressed) {
break;
}
}
} else if (isUpPressed) {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
break;
}
System.out.println("move(1, 'y') -- 地图上移");
if (!isUpPressed) {
break;
}
}
}
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
这个是最简单的一个实现,可以在这个基础上扩展出很多应用,比如两个键同时longPressed。根据需要,自己定制。
ps:以上实现的思路来自于众多j2me前辈,感谢他们的无私奉献。