javax.microedition.lcdui.Canvas 是低層 UI 基類,提供完全繪製控制權:
paint(Graphics g) 實作自定繪製。keyPressed/Released/Repeated(int keyCode) 處理按鍵。Command + CommandListener 實現軟鍵選單。
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class CanvasDemo extends MIDlet implements CommandListener {
private Display display;
private MyCanvas canvas;
private List fontSizeList;
private Command okCmd, exitCmd, backCmd;
public CanvasDemo() {
// 1. 字體選擇清單 (高層 UI)
fontSizeList = new List("選擇字體大小", Choice.EXCLUSIVE);
fontSizeList.append("Small", null);
fontSizeList.append("Medium", null);
fontSizeList.append("Large", null);
okCmd = new Command("確定", Command.OK, 1);
exitCmd = new Command("離開", Command.EXIT, 1);
fontSizeList.addCommand(okCmd);
fontSizeList.addCommand(exitCmd);
fontSizeList.setCommandListener(this);
// 2. 自定 Canvas (低層 UI)
canvas = new MyCanvas();
backCmd = new Command("返回", Command.BACK, 1);
canvas.addCommand(backCmd);
canvas.setCommandListener(this);
}
protected void startApp() {
display = Display.getDisplay(this);
display.setCurrent(fontSizeList);
}
protected void pauseApp() {}
protected void destroyApp(boolean unconditional) {}
public void commandAction(Command c, Displayable d) {
if (d == fontSizeList) { // 清單介面
if (c == exitCmd) { destroyApp(false); notifyDestroyed(); }
else if (c == okCmd) {
int idx = fontSizeList.getSelectedIndex();
int size = (idx == 0) ? Font.SIZE_SMALL :
(idx == 1) ? Font.SIZE_MEDIUM : Font.SIZE_LARGE;
canvas.setFontSize(size);
display.setCurrent(canvas);
}
} else if (d == canvas) { // Canvas 介面
if (c == backCmd) display.setCurrent(fontSizeList);
}
}
// 內部 Canvas 類別
class MyCanvas extends Canvas {
private Font font;
public MyCanvas() {
font = Font.getDefaultFont();
}
public void setFontSize(int size) {
font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, size);
}
protected void paint(Graphics g) {
// 1. 清除畫面 (關鍵!低層 UI 無自動清除)
g.setColor(0x00808080); // 灰色背景
g.fillRect(0, 0, getWidth(), getHeight());
// 2. 繪製文字
g.setColor(0xFFFFFF); // 白色文字
g.setFont(font);
String txt = "Hello Canvas";
g.drawString(txt, getWidth()/2, getHeight()/2,
Graphics.HCENTER | Graphics.VCENTER);
// 3. 繪製圖形示例
g.setColor(0xFF0000);
g.drawLine(0, 0, getWidth(), getHeight());
}
protected void keyPressed(int keyCode) {
// 可處理遊戲按鍵,此處不需要
}
}
}
// 系統預設字體
Font f = Font.getDefaultFont();
// 依面貌/風格/大小取得 (標準方式)
Font f = Font.getFont(int face, int style, int size);
| 屬性 | 常量 | 說明 |
|---|---|---|
| 面貌 | FACE_SYSTEM, FACE_MONOSPACE, FACE_PROPORTIONAL | 系統預設、等寬、比例字體 |
| 風格 | STYLE_PLAIN, STYLE_BOLD, STYLE_ITALIC, STYLE_UNDERLINED | 可組合 (如 STYLE_BOLD | STYLE_ITALIC) |
| 大小 | SIZE_SMALL, SIZE_MEDIUM, SIZE_LARGE | 相對大小,實際像素由裝置決定 |
int h = font.getHeight(); // 行高
int baseline = font.getBaselinePosition(); // 基線位置
int charW = font.charWidth('中'); // 單字寬度
int strW = font.stringWidth("Hello"); // 字串寬度
int subW = font.substringWidth(s, 0, 3); // 子串寬度
int charsW = font.charsWidth(chArr, 0, len); // 字元陣列寬度
(0,0) 位於螢幕左上角。| 常量 | 水平對齊 | 垂直對齊 |
|---|---|---|
LEFT | 左對齊 | - |
RIGHT | 右對齊 | - |
HCENTER | 水平置中 | - |
TOP | - | 頂對齊 |
BOTTOM | - | 底對齊 |
VCENTER | - | 垂直置中 |
BASELINE | - | 文字基線對齊 |
組合使用:Graphics.HCENTER | Graphics.VCENTER 畫面正中心。
「既然使用了低層界面,意味著螢幕上的一切都歸你管,你有最大的權利。但你也有相應的義務:清除螢幕、管理狀態、處理所有輸入,自然也要你來做。」
g.fillRect(0,0,getWidth(),getHeight()) 或 g.drawImage(bg,0,0,...)。keyPressed 處理。public void MyCanvas() (加了 void 變成方法) → 物件無法建立、畫面空白。setCommandListener(this) → 軟鍵無反應。getWidth()/2 相對座標。