MIDP (Mobile Information Device Profile) 事件處理分為高階與低階兩層。高階事件透過 CommandListener、ItemStateListener 處理選單、表單元件互動;低階事件 直接對應硬體輸入(按鍵、觸控筆、觸控螢幕),是遊戲、繪圖、即時互動應用的核心。本文系統梳理低階事件機制、關鍵方法、按鍵常數與完整實作範例。
| 方法 | 參數 | 觸發時機 | 備註 |
|---|---|---|---|
keyPressed(int keyCode) | 按鍵代碼 | 按鍵被按下 | 主力處理方法 |
keyReleased(int keyCode) | 按鍵代碼 | 按鍵被釋放 | 配合 pressed 判斷長按/點擊 |
keyRepeated(int keyCode) | 按鍵代碼 | 按鍵長按重複觸發 | 需先檢查 hasRepeatEvents() |
pointerPressed(int x, int y) | 螢幕座標 | 觸控/滑鼠按下 | 需先檢查 hasPointerEvents() |
pointerDragged(int x, int y) | 螢幕座標 | 觸控/滑鼠拖曳 | 持續觸發 |
pointerReleased(int x, int y) | 螢幕座標 | 觸控/滑鼠釋放 | 完成點擊/拖曳手勢 |
showNotify() | 無 | Canvas 顯示於螢幕 | 初始化資源、啟動動畫執行緒 |
hideNotify() | 無 | Canvas 從螢幕移除 | 釋放資源、停止動畫執行緒 |
paint(Graphics g) | 繪圖上下文 | 需重繪時 (init/repaint) | 抽象方法,必須實作 |
KEY_NUM0 KEY_NUM1 KEY_NUM2 KEY_NUM3 KEY_NUM4
KEY_NUM5 KEY_NUM6 KEY_NUM7 KEY_NUM8 KEY_NUM9
KEY_STAR (*鍵) KEY_POUND (#鍵)
可移植性原則:盡量使用上述標準鍵值,避免依賴特定裝置的專屬按鍵代碼。遊戲建議提供按鍵配置功能讓使用者自訂。
paint() 亦同。耗時運算需另開執行緒,避免阻塞 UI。hasRepeatEvents()、hasPointerEvents()、hasPointerMotionEvents() 動態適配。import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class KeyEventDemo extends MIDlet {
private Display display;
private KeyCanvas canvas;
protected void startApp() {
display = Display.getDisplay(this);
canvas = new KeyCanvas();
display.setCurrent(canvas);
}
protected void pauseApp() {}
protected void destroyApp(boolean unconditional) {}
}
class KeyCanvas extends Canvas implements CommandListener {
private String msg = "Press any key";
private Command exitCmd = new Command("Exit", Command.EXIT, 1);
public KeyCanvas() { addCommand(exitCmd); setCommandListener(this); }
protected void paint(Graphics g) {
g.setColor(0xFFFFFF); g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0x000000);
g.drawString(msg, getWidth()/2, getHeight()/2, Graphics.TOP | Graphics.HCENTER);
}
protected void keyPressed(int keyCode) {
msg = "Pressed: " + keyCode + " (" + getKeyName(keyCode) + ")";
repaint();
}
protected void keyReleased(int keyCode) {
msg = "Released: " + keyCode + " (" + getKeyName(keyCode) + ")";
repaint();
}
protected void keyRepeated(int keyCode) {
if (hasRepeatEvents()) {
msg = "Repeated: " + keyCode;
repaint();
}
}
protected void pointerPressed(int x, int y) {
if (hasPointerEvents()) {
msg = "Touch: " + x + "," + y;
repaint();
}
}
public void commandAction(Command c, Displayable d) {
if (c == exitCmd) notifyDestroyed();
}
}
paint() 僅負責渲染,遊戲邏輯 (位移、碰撞、AI) 放在獨立執行緒 run() 中,透過 repaint() 觸發重繪。Image offscreen = Image.createImage(w,h); Graphics og = offscreen.getGraphics(); 繪製完成後 g.drawImage(offscreen,0,0,0); 減少閃爍。boolean[] keyStates 陣列,在 keyPressed/Released 更新,遊戲迴圈輪詢狀態實現平滑移動。pointerPressed 起始點、pointerDragged 移動向量、pointerReleased 結束點,判斷滑動、縮放、點擊等手勢。MIDP 低階事件機制以 Canvas 為核心,提供按鍵、觸控、生命週期回調。掌握標準按鍵常數、裝置能力查詢、串行事件模型與繪圖執行緒分離,是開發流暢 Java ME 遊戲與互動應用的基石。雖 Java ME 已淡出主流,但其事件模型設計思想對理解 Android View 觸控事件、嵌入式 UI 框架仍有參考價值。