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

J2ME Canvas 字體進階:Font 三屬性組合、ChoiceGroup 多選風格與畫面清除最佳實踐

     編輯:J2ME

Font 三屬性完整組合指南

Font.getFont(face, style, size) 三參數獨立正交,可自由組合:

屬性常量組合示例
面貌SYSTEM, MONOSPACE, PROPORTIONALFACE_SYSTEM
風格PLAIN, BOLD, ITALIC, UNDERLINEDSTYLE_BOLD | STYLE_ITALIC (位或運算)
大小SMALL, MEDIUM, LARGESIZE_LARGE

風格位運算詳解


// 單一風格
Font f1 = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM);

// 組合風格 (粗體+斜體+底線)
int style = Font.STYLE_BOLD | Font.STYLE_ITALIC | Font.STYLE_UNDERLINED;
Font f2 = Font.getFont(Font.FACE_PROPORTIONAL, style, Font.SIZE_LARGE);

// 移除風格
style = style & ~Font.STYLE_ITALIC; // 去掉斜體

完整範例:字體屬性選擇器 (ChoiceGroup 多選風格)


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

public class FontChooserDemo extends MIDlet implements CommandListener {
    private Form form;
    private ChoiceGroup faceGroup, styleGroup, sizeGroup;
    private Command okCmd, exitCmd, backCmd;
    private Display display;
    private FontCanvas canvas;
    private int face = Font.FACE_SYSTEM;
    private int style = Font.STYLE_PLAIN;
    private int size = Font.SIZE_MEDIUM;

    public FontChooserDemo() {
        form = new Form("字體屬性設定");

        // 1. 面貌 (單選)
        faceGroup = new ChoiceGroup("面貌", Choice.EXCLUSIVE);
        faceGroup.append("SYSTEM", null);
        faceGroup.append("MONOSPACE", null);
        faceGroup.append("PROPORTIONAL", null);
        faceGroup.setSelectedIndex(0, true);

        // 2. 風格 (多選 - 關鍵:Choice.MULTIPLE)
        styleGroup = new ChoiceGroup("風格", Choice.MULTIPLE);
        styleGroup.append("PLAIN", null);
        styleGroup.append("BOLD", null);
        styleGroup.append("ITALIC", null);
        styleGroup.append("UNDERLINED", null);
        styleGroup.setSelectedIndex(0, true); // 預設 PLAIN

        // 3. 大小 (單選)
        sizeGroup = new ChoiceGroup("大小", Choice.EXCLUSIVE);
        sizeGroup.append("SMALL", null);
        sizeGroup.append("MEDIUM", null);
        sizeGroup.append("LARGE", null);
        sizeGroup.setSelectedIndex(1, true); // 預設 MEDIUM

        form.append(faceGroup);
        form.append(styleGroup);
        form.append(sizeGroup);

        okCmd = new Command("確定", Command.OK, 1);
        exitCmd = new Command("離開", Command.EXIT, 1);
        form.addCommand(okCmd);
        form.addCommand(exitCmd);
        form.setCommandListener(this);

        canvas = new FontCanvas();
        backCmd = new Command("返回", Command.BACK, 1);
        canvas.addCommand(backCmd);
        canvas.setCommandListener(this);
    }

    protected void startApp() {
        display = Display.getDisplay(this);
        display.setCurrent(form);
    }
    protected void pauseApp() {}
    protected void destroyApp(boolean unconditional) {}

    public void commandAction(Command c, Displayable d) {
        if (d == form) {
            if (c == exitCmd) { destroyApp(false); notifyDestroyed(); }
            else if (c == okCmd) {
                // 讀取面貌
                face = new int[]{Font.FACE_PROPORTIONAL, Font.FACE_MONOSPACE, Font.FACE_SYSTEM}
                        [faceGroup.getSelectedIndex()];

                // 讀取大小
                size = new int[]{Font.SIZE_SMALL, Font.SIZE_MEDIUM, Font.SIZE_LARGE}
                        [sizeGroup.getSelectedIndex()];

                // 讀取風格 (多選位運算)
                style = 0;
                boolean[] selected = new boolean[4];
                styleGroup.getSelectedFlags(selected);
                if (selected[0]) style |= Font.STYLE_PLAIN;
                if (selected[1]) style |= Font.STYLE_BOLD;
                if (selected[2]) style |= Font.STYLE_ITALIC;
                if (selected[3]) style |= Font.STYLE_UNDERLINED;

                display.setCurrent(canvas);
            }
        } else if (d == canvas) {
            if (c == backCmd) display.setCurrent(form);
        }
    }

    class FontCanvas extends Canvas {
        public FontCanvas() {
            addCommand(backCmd);
            setCommandListener(this);
        }

        protected void paint(Graphics g) {
            // 關鍵:每幀必清除畫面
            g.setColor(0xFFFFFF); // 白底
            g.fillRect(0, 0, getWidth(), getHeight());

            g.setColor(0x000000); // 黑字
            Font f = Font.getFont(face, style, size);
            g.setFont(f);
            String txt = "Hello J2ME Font";
            g.drawString(txt, getWidth()/2, getHeight()/2, 
                         Graphics.HCENTER | Graphics.VCENTER);
        }
    }
}

ChoiceGroup 多選模式 (MULTIPLE) 核心 API

方法說明
getSelectedFlags(boolean[])批次讀取所有項目選中狀態,陣列長度需 >= size()
setSelectedFlags(boolean[])批次設定選中狀態
isSelected(int index)檢查單項是否選中
getSelectedIndex()僅返回第一個選中項索引 (不適合多選)

畫面清除機制:低層 UI 鐵律

Canvas 無自動清除,每幀 paint() 必須以 fillRect 或 drawImage(背景) 覆蓋全螢幕,否則上一幀殘影疊加。


// 標準清除模式
protected void paint(Graphics g) {
    // 1. 純色清除
    g.setColor(0xFFFFFF); // 背景色
    g.fillRect(0, 0, getWidth(), getHeight());

    // 或 2. 背景圖清除 (若有背景圖)
    // g.drawImage(bgImage, 0, 0, Graphics.TOP | Graphics.LEFT);

    // 3. 繪製前景內容...
    g.setColor(0x000000); // 前景色
    // ...
}

常見錯誤與修正

錯誤代碼現象修正
public void MyCanvas()建構子加 void 變成方法,物件不建立public MyCanvas() (無返回類型)
忘記 fillRect文字/圖形疊加、殘影每幀首行 g.fillRect(0,0,w,h)
用 getSelectedIndex() 讀多選只得第一個選中項用 getSelectedFlags(boolean[])
風格直接相加 STYLE_BOLD + STYLE_ITALIC數值錯誤 (非位運算)STYLE_BOLD | STYLE_ITALIC

效能優化建議

  • Font 物件緩存復用:setFontSize() 時建立新 Font,paint() 直接用緩存,避免每幀 getFont()。
  • 背景圖若不變,drawImage 比 fillRect 更有質感且同等快。
  • 大量文字繪製時,預先計算 stringWidth() 佈局座標,避免 paint 內重複計算。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved