首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 學習筆記(五):高級/低級事件處理機制全解析

     編輯:J2ME

前言:事件驅動是 MIDP 交互的靈魂

MIDP 將事件處理分為高級 (High-Level) 與低級 (Low-Level)兩套體系。高級面向「邏輯動作」(命令、項目值變化),低級面向「物理輸入」(鍵盤、觸控筆、繪圖)。本文逐層拆解接口、類、常量、實戰模式。

一、 高級事件:CommandListener & ItemStateListener

1. CommandListener

  • 綁定對象:繼承 Displayable 的類 (Screen、Canvas)。
  • 註冊:setCommandListener(this) + addCommand(Command)。
  • 回調:commandAction(Command c, Displayable d)。
  • Command 類型與優先級 (高→低):
    BACK > CANCEL > EXIT > HELP > ITEM > OK > SCREEN > STOP。
    同類型按添加順序排列。設備自動映射到軟鍵/菜單。
  • 單播模型:同一時刻只響應一個命令。

2. ItemStateListener

  • 針對 Item 子類 (TextField, ChoiceGroup, Gauge 等) 的值變化。
  • 註冊:form.setItemStateListener(this)。
  • 回調:itemStateChanged(Item item)。
  • 優先級高於 CommandListener:同一用戶操作同時觸發項目變化與命令時,先調用 itemStateChanged。

3. 實戰:表單輸入實時計算

public class CalculatorForm extends Form implements CommandListener, ItemStateListener {
    private TextField a = new TextField("A", "", 6, TextField.NUMERIC);
    private TextField b = new TextField("B", "", 6, TextField.NUMERIC);
    private TextField sum = new TextField("Sum", "", 6, TextField.NUMERIC | TextField.UNEDITABLE);

    public CalculatorForm() {
        super("Calc");
        append(a); append(b); append(sum);
        setItemStateListener(this);
        addCommand(new Command("Exit", Command.EXIT, 1));
        setCommandListener(this);
    }

    public void itemStateChanged(Item item) {
        try {
            int va = Integer.parseInt(a.getString());
            int vb = Integer.parseInt(b.getString());
            sum.setString(String.valueOf(va + vb));
        } catch (NumberFormatException e) {
            sum.setString("");
        }
    }
    public void commandAction(Command c, Displayable d) {
        if (c.getCommandType() == Command.EXIT) { /* exit */ }
    }
}

二、 低級事件:Canvas 直接掌控

Canvas 繼承 Displayable,但不允許註冊外部 Listener,必須繼承並覆寫 protected 方法:

方法觸發條件參數典型用途
keyPressed(int keyCode)按鍵按下鍵碼 (見下)遊戲移動、確認
keyReleased(int keyCode)按鍵釋放鍵碼鬆開停止移動
keyRepeated(int keyCode)長按重複 (設備支持時)鍵碼連續移動/加速
pointerPressed(int x, int y)觸控筆/鼠標按下屏幕座標點擊按鈕、拖拽起點
pointerReleased(int x, int y)觸控筆抬起座標拖拽終點、點擊確認
pointerDragged(int x, int y)觸控筆移動座標滑動、繪圖
paint(Graphics g)系統請求重繪Graphics遊戲幀渲染、自定義 UI

關鍵常量:跨平台鍵碼

// 標準鍵 (所有設備必支持)
Canvas.KEY_NUM0 ... KEY_NUM9, KEY_STAR (*), KEY_POUND (#)

// 游戲鍵映射 (邏輯方向,由 getGameAction(keyCode) 轉換)
Canvas.UP, DOWN, LEFT, RIGHT, FIRE, GAME_A, GAME_B, GAME_C, GAME_D

// 檢測能力
boolean hasRepeat = hasRepeatEvents();        // 是否支持 keyRepeated
boolean hasPointer = hasPointerEvents();      // 是否支持觸控筆
boolean hasPointerMotion = hasPointerMotionEvents(); // 是否支持 pointerDragged

實戰:鍵盤測試 Canvas

public class KeyTestCanvas extends Canvas {
    String msg = "";
    protected void paint(Graphics g) {
        g.setColor(0xFFFFFF); g.fillRect(0,0,getWidth(),getHeight());
        g.setColor(0); g.drawString(msg, 10, 10, 0);
        g.drawString(hasRepeatEvents() ? "Repeat" : "NoRepeat", 10, 30, 0);
    }
    protected void keyPressed(int kc) { msg = "KP:" + kc + "(" + getGameAction(kc) + ")"; repaint(); }
    protected void keyReleased(int kc) { msg = "KR:" + kc; repaint(); }
    protected void keyRepeated(int kc) { msg = "KRe:" + kc; repaint(); }
}

三、 繪圖與雙緩衝 (低級 UI 必修課)

  • Graphics 方法:drawLine, fillRect, drawString, drawImage, drawRegion (圖片區域/旋轉/鏡像)。
  • 雙緩衝:Image offscreen = Image.createImage(w,h); Graphics og = offscreen.getGraphics(); → 離屏繪圖 → g.drawImage(offscreen,0,0,0); 避免閃爍。
  • 動畫循環:獨立線程 while(running) { update(); repaint(); sleep(40); } 或 Timer.schedule。

四、 總結對比

維度高級事件低級事件
抽象層級語義動作 (確認、取消、輸入變化)物理輸入 (按鍵、觸控、繪圖)
可移植性極高 (設備自動映射)需自行處理鍵碼差異、屏幕尺寸
適用場景表單、列表、菜單、設置向導遊戲、自定義組件、繪圖工具
代碼複雜度低高 (需自行管理狀態、幀循環)
組合使用Canvas 可 addCommand 同時支持高級命令Screen 不支持低級回調

五、 最佳實踐

  1. 優先用高級 UI 構建業務流程;只有遊戲/特殊交互才繼承 Canvas。
  2. Canvas 中絕不在 paint() 做邏輯計算,只做渲染;邏輯放 update() 或線程中。
  3. 鍵盤處理用 getGameAction() 統一邏輯方向,避免硬編碼鍵碼。
  4. 觸控筆事件前必須 hasPointerEvents() 守衛,不支持設備優雅降級。
  5. 釋放資源:Image 用完 null 引用輔助 GC,Player close(),RecordStore closeRecordStore()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved