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

深入解析 MIDP 底層用戶介面 API:Canvas 與 Graphics 實戰指南

     編輯:J2ME

MIDP 雙層 UI 架構概覽

在 J2ME 平台上,MIDP 定義了兩套截然不同的用戶介面 API:

  • 高層 API:面向業務邏輯的抽象元件(如 Form、List、Alert),由實現方決定具體繪製細節,適合商務應用,具備極佳的跨設備可移植性。
  • 底層 API:直接操作螢幕像素與原始輸入事件,核心類為 Canvas 與 Graphics,專為遊戲與高度自定義介面設計,開發者需自行處理所有繪圖邏輯。

兩種 API 可在同一 MIDlet 中共存,但單一 Displayable(螢幕)同一時間只能採用其中一種。命令對象(Command)是唯一可跨越兩種 API 的例外。

核心類別:Canvas 與 Graphics

所有底層 UI 類別位於 javax.microedition.lcdui 套件。要使用底層 API,必須繼承 Canvas 並實作 paint(Graphics g) 方法:

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class MyCanvas extends Canvas {
    private MIDlet midlet;

    public MyCanvas(MIDlet midlet) {
        this.midlet = midlet;
    }

    protected void paint(Graphics g) {
        // 清空螢幕為白色
        g.setColor(0xFFFFFF);
        g.fillRect(0, 0, getWidth(), getHeight());
        // 置中繪製文字
        g.setColor(0x000000);
        g.drawString("Hello there!", getWidth()/2, 0, Graphics.TOP | Graphics.HCENTER);
    }
}

Graphics 提供了豐富的繪圖原語:drawLine、drawRect、drawArc、drawString 等,座標原點位於螢幕左上角。

啟動 Canvas

在 MIDlet 的 startApp() 中透過 Display.setCurrent() 顯示 Canvas:

public class MyMIDlet extends MIDlet {
    private Display display;
    private MyCanvas canvas;

    public MyMIDlet() {
        display = Display.getDisplay(this);
        canvas = new MyCanvas(this);
    }

    protected void startApp() {
        display.setCurrent(canvas);
    }
    // pauseApp、destroyApp 略...
}

處理使用者輸入:按鍵與指標事件

Canvas 提供完整的事件回呼機制:

  • 按鍵事件:keyPressed(int keyCode)、keyRepeated、keyReleased。keyCode 正值對應 Unicode 字元,負值為功能鍵。為消除設備差異,Canvas 定義了遊戲鍵常數(UP、DOWN、LEFT、RIGHT、FIRE 等),可透過 getKeyCode(int gameAction) 取得實際鍵碼。
  • 指標事件:pointerPressed(x, y)、pointerDragged、pointerReleased。並非所有設備皆支援,需先用 hasPointerEvents() 檢測。
  • 可見性事件:showNotify()、hideNotify()。

建立遊戲按鍵基礎類別

public abstract class GameCanvas extends Canvas {
    protected MIDlet midlet;
    protected int fireKey, leftKey, rightKey, upKey, downKey;

    public GameCanvas(MIDlet midlet) {
        this.midlet = midlet;
        fireKey = getKeyCode(FIRE);
        leftKey = getKeyCode(LEFT);
        rightKey = getKeyCode(RIGHT);
        upKey = getKeyCode(UP);
        downKey = getKeyCode(DOWN);
    }
}

繼承此類別即可輕鬆處理方向鍵與確認鍵:

public class MyCanvas extends GameCanvas {
    private String message = "Press any key";

    public MyCanvas(MIDlet midlet) { super(midlet); }

    protected void paint(Graphics g) {
        g.setColor(0xFFFFFF); g.fillRect(0,0,getWidth(),getHeight());
        g.setColor(0x000000);
        g.drawString(message, getWidth()/2, 0, Graphics.TOP|Graphics.HCENTER);
    }

    protected void keyPressed(int keyCode) {
        if (keyCode == fireKey) message = "FIRE";
        else if (keyCode == leftKey) message = "LEFT";
        else if (keyCode == rightKey) message = "RIGHT";
        else if (keyCode == upKey) message = "UP";
        else if (keyCode == downKey) message = "DOWN";
        else message = getKeyName(keyCode);
        repaint();
    }
}

命令機制:統一的交互抽象

命令(Command)封裝了動作的標籤、類型與優先序,裝置負責將其對應到實體按鍵。支援類型包括 BACK、CANCEL、EXIT、HELP、OK、SCREEN、STOP 等。優先序為正整數,1 為最高。

Command exitCmd = new Command("Exit", Command.SCREEN, 1);
canvas.addCommand(exitCmd);
canvas.setCommandListener(this); // 實作 CommandListener

CommandListener 僅定義一個方法 commandAction(Command c, Displayable d),通常由 MIDlet 主類別實作:

public class MyMIDlet extends MIDlet implements CommandListener {
    // ... 建構子與 startApp 同前 ...
    public void commandAction(Command c, Displayable d) {
        if (c == exitCmd) { destroyApp(true); notifyDestroyed(); }
    }
}

同一命令物件可被多個 Canvas 共用,高層 API 元件亦同理。

最佳實踐提醒

  1. 盡量使用高層 API 開發商務應用,保證可移植性;僅在需要像素級控制(如遊戲)時採用底層 API。
  2. 善用 GameCanvas 封裝鍵碼映射,減少硬編碼。
  3. 指標事件視為輔助輸入,務必提供鍵盤替代方案。
  4. 命令類型與優先序應符合平台慣例(如「返回」用 BACK、「確認」用 OK),提升使用者體驗一致性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved