這是一個極簡的 MIDlet 範例,示範如何在 Canvas 中處理命令事件(繪圖切換、退出),並使用獨立執行緒驅動遊戲主迴圈。適合初學者理解 J2ME 事件模型與繪圖基礎。
MIDlet,持有 Display 與 MiracleCanvas 實例,負責生命週期。Canvas 並實作 Runnable、CommandListener,內含繪圖迴圈與命令處理。// MiracleMIDlet.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class MiracleMIDlet extends MIDlet {
private Display display;
private MiracleCanvas canvas;
public MiracleMIDlet() {
canvas = new MiracleCanvas(this);
}
protected void startApp() {
display = Display.getDisplay(this);
display.setCurrent(canvas);
}
protected void pauseApp() { }
protected void destroyApp(boolean unconditional) { }
}
// MiracleCanvas.java
import javax.microedition.lcdui.*;
public class MiracleCanvas extends Canvas implements Runnable, CommandListener {
private MiracleMIDlet midlet;
private Thread thread;
private int width, height;
private boolean showText = false;
private final Command cmdDraw = new Command("畫字", Command.OK, 1);
private final Command cmdExit = new Command("退出", Command.EXIT, 0);
private int frame = 6;
private final int[] offset = {0,0,0,0,0,0,0,1,2,3,3,2,1,0,0,0,0,0,0,0};
public MiracleCanvas(MiracleMIDlet midlet) {
this.midlet = midlet;
width = getWidth(); height = getHeight();
setFullScreenMode(true);
addCommand(cmdDraw); addCommand(cmdExit);
setCommandListener(this);
thread = new Thread(this); thread.start();
}
public void run() {
while (true) {
repaint();
try { Thread.sleep(70); } catch (Exception ignore) {}
frame++; if (frame >= offset.length) frame = 6;
}
}
protected void paint(Graphics g) {
g.setColor(0xFFFFFF); g.fillRect(0, 0, width, height);
g.setColor(0x000000);
String msg = "PRESS 5";
for (int i = 0; i < msg.length(); i++) {
int y = 10 - offset[frame - i];
g.drawString(msg.substring(i, i+1), 20 + i*7, y, Graphics.TOP | Graphics.LEFT);
g.drawString(msg.substring(i, i+1), 21 + i*7, y+1, Graphics.TOP | Graphics.LEFT); // 加粗
}
if (showText) {
g.setColor(0xFF00FF);
g.drawString("drawing...", 64, 100, Graphics.TOP | Graphics.LEFT);
}
}
public void commandAction(Command c, Displayable d) {
if (c == cmdDraw) showText = !showText;
else if (c == cmdExit) { midlet.destroyApp(true); midlet.notifyDestroyed(); }
}
}
drawString(x, y, anchor) 的錨點常用 Graphics.TOP | Graphics.LEFT。repaint() 觸發 paint(),配合 Thread.sleep 控制幀率。Canvas 實作 CommandListener,透過 addCommand 註冊軟鍵選單。destroyApp(true) 後再 notifyDestroyed()。將兩個類別存為同名 .java 檔,用 WTK 或 NetBeans 即可編譯執行,按左軟鍵切換文字、右軟鍵退出,觀察波浪式文字動畫效果。