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

J2ME 低階 UI 文字自動換行繪製實作

     編輯:J2ME

問題背景

在 MIDP 低階 Canvas 開發中,Graphics.drawString() 並不支援自動換行。當需在有限螢幕寬度顯示長字串(如對話框、說明文字)時,必須自行實作「按像素寬度斷行」的邏輯。

核心演算法思路

  1. 取得目前字體 Font 實例。
  2. 逐字累加字元寬度(font.charWidth())。
  3. 當累計寬度超過可用區寬(通常 getWidth() - padding),將目前累積的子字串存入 Vector,重置累計寬度與起始索引。
  4. 迴圈結束後,將剩餘子字串加入 Vector。
  5. 繪製時逐行呼叫 drawString(),Y 座標每行遞增 font.getHeight()。

完整可用程式碼

import javax.microedition.lcdui.*;

public class TextWrapCanvas extends Canvas {
    private Vector lines;
    private Font font;
    private String longText = "這是一段很長的測試文字,用來驗證在 J2ME 低階介面下的自動換行繪製效果。";

    public TextWrapCanvas() {
        font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM);
        lines = splitText(longText);
    }

    /** 依螢幕寬度將字串切割成多行 */
    private Vector splitText(String text) {
        Vector v = new Vector();
        int availW = getWidth() - 4;           // 左右各保留 2px
        int start = 0;
        int accW = 0;

        for (int i = 0; i < text.length(); i++) {
            accW += font.charWidth(text.charAt(i));
            if (accW >= availW) {
                v.addElement(text.substring(start, i));
                start = i;
                accW = font.charWidth(text.charAt(i)); // 當前字元重新計算
            }
        }
        v.addElement(text.substring(start)); // 最後一段
        return v;
    }

    protected void paint(Graphics g) {
        g.setColor(0xFFFFFF);
        g.fillRect(0, 0, getWidth(), getHeight());

        g.setFont(font);
        g.setColor(0x000000);

        int lineH = font.getHeight();
        int y = (getHeight() - lines.size() * lineH) / 2; // 垂直置中
        for (int i = 0; i < lines.size(); i++) {
            g.drawString((String) lines.elementAt(i), 2, y + i * lineH, Graphics.LEFT | Graphics.TOP);
        }
    }
}

關鍵細節補充

  • 英文單字不斷行:上述演算法以「字元」為單位切割,英文長單字可能被硬切。若需避免,可在遇到空白鍵時記錄「可斷點」,超寬時回退到最近可斷點。
  • 效能考量:Font.charWidth() 呼叫成本極低,但若文字極長(超過數千字),建議在背景執行緒預先切割好再交給 paint(),避免畫面卡頓。
  • 滾動支援:若行數超過螢幕可顯示範圍,可加入 keyPressed() 處理 UP/DOWN 捲動 y 起始偏移量。

擴充建議

將切割邏輯封裝為靜態工具類 TextUtils.wrap(String, Font, int) 回傳 String[],並支援對齊方式(左/中/右)、行間距、縮排等參數,即可在專案中複用於選單、說明頁、聊天氣泡等多種場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved