MIDP 定義兩套 UI API:高階 API(Form/List 等,面向語意、自動排版、跨裝置可移植)與 低階 API(Canvas,掌握完整繪圖與事件控制權,適合遊戲開發)。兩者可在同一應用中混用(如撲克牌切換),但同一畫面只能二擇一,唯 Command 物件可共用。
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);
}
}
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 略...
}
protected void keyPressed(int keyCode) {
// 直接結束應用範例
((MyMIDlet) midlet).exit();
}
按鍵代碼映射:正值為 Unicode 字元,負值為功能鍵。為跨裝置相容,Canvas 定義遊戲動作常數:UP, DOWN, LEFT, RIGHT, FIRE, GAME_A~D。可用 getGameAction(keyCode) 轉換,getKeyCode(action) 反查。
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();
}
}
// 檢測是否支援指標
if (hasPointerEvents()) {
// 可用 pointerPressed/Dragged/Released
}
protected void pointerPressed(int x, int y) {
// 處理觸控/滑鼠點擊
}
// MIDlet 實作 CommandListener
public class MyMIDlet extends MIDlet implements CommandListener {
private Display display;
private MyCanvas canvas;
private Command exitCmd = new Command("離開", Command.EXIT, 1);
public MyMIDlet() {
display = Display.getDisplay(this);
canvas = new MyCanvas(this);
canvas.addCommand(exitCmd);
canvas.setCommandListener(this);
}
protected void startApp() { display.setCurrent(canvas); }
public void commandAction(Command c, Displayable d) {
if (c == exitCmd) { destroyApp(true); notifyDestroyed(); }
}
// 其他方法略...
}
Command 含 label、type(BACK/CANCEL/EXIT/HELP/ITEM/OK/SCREEN/STOP)、priority(1 最高)type 映射實體鍵,衝突時依 priority 排序Command 可在多個 Canvas 間共用Graphics 提供:drawArc、drawLine、drawRect、drawString、fillRect、setColor、translate 等,座標原點可平移。
掌握 Canvas 繪圖、事件、命令三大核心,即可構建高效能的 J2ME 遊戲與低階應用。