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

J2ME Canvas 低層 UI 入門:字體繪製、繪圖座標系與畫面清除機制

     編輯:J2ME

Canvas 核心架構

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 物件


// 系統預設字體
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相對大小,實際像素由裝置決定

Font 度量方法 (佈局必備)


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) 位於螢幕左上角。
  • X 向右遞增,Y 向下遞增 (非笛卡兒座標系)。
  • 座標代表像素格線交點,非像素本身 (畫線時線寬為 1 像素,佔據座標間空間)。

定位點常量 (anchor)

常量水平對齊垂直對齊
LEFT左對齊-
RIGHT右對齊-
HCENTER水平置中-
TOP-頂對齊
BOTTOM-底對齊
VCENTER-垂直置中
BASELINE-文字基線對齊

組合使用:Graphics.HCENTER | Graphics.VCENTER 畫面正中心。

低層 UI 核心心法:權力與責任對等

「既然使用了低層界面,意味著螢幕上的一切都歸你管,你有最大的權利。但你也有相應的義務:清除螢幕、管理狀態、處理所有輸入,自然也要你來做。」

  • ✅ 每幀必清除:g.fillRect(0,0,getWidth(),getHeight()) 或 g.drawImage(bg,0,0,...)。
  • ✅ 狀態自管:遊戲狀態、動畫幀、分數、生命值全靠自己維護。
  • ✅ 輸入全攬:數字鍵/方向鍵/功能鍵/觸控 (MIDP 3.0) 全在 keyPressed 處理。

常見新手錯誤

  • ❌ 建構子寫成 public void MyCanvas() (加了 void 變成方法) → 物件無法建立、畫面空白。
  • ❌ 忘記 setCommandListener(this) → 軟鍵無反應。
  • ❌ 不清除畫面直接繪製 → 殘影疊加、畫面混亂。
  • ❌ 用絕對座標 (如 150,250) → 換機型位置錯位,改用 getWidth()/2 相對座標。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved