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

J2ME 低階 UI 文字自動換行演算法(支援中英日文)

     編輯:J2ME

問題背景

在 Canvas 低階繪圖上顯示長文字(如 RPG 對話),需自動依螢幕寬度換行。英文不可拆分單字,中日文可逐字換行。

通用換行方法:getSubsection

/**
 * 將文字依指定字體與寬度分行
 * @param strSource  原始字串
 * @param font       使用字體
 * @param width      最大像素寬度
 * @param strSplit   斷詞分隔字元(英文用 " ,.?!",中文傳 "")
 * @return Vector<String> 每一行文字
 */
public Vector getSubsection(String strSource, Font font, int width, String strSplit) {
    Vector lines = new Vector();
    String temp = strSource;
    int lastLen = 1;

    try {
        while (!temp.equals("")) {
            int i = temp.indexOf('\n');
            // 手動換行優先處理
            if (i > 0 && font.stringWidth(temp.substring(0, i)) <= width) {
                // 保留手動換行
            } else {
                i = -1;
            }

            if (i == -1) {
                // 尋找適合寬度的臨界點
                if (lastLen > temp.length()) i = temp.length();
                else {
                    i = lastLen;
                    int step = font.stringWidth(temp.substring(0, i)) > width ? -1 : 1;
                    while (i < temp.length() &&
                           !(font.stringWidth(temp.substring(0, i)) <= width &&
                             font.stringWidth(temp.substring(0, i+1)) > width)) {
                        i += step;
                    }
                }
                // 英文斷詞處理
                if (!strSplit.equals("") && i < temp.length()) {
                    int j = i;
                    while (strSplit.indexOf(temp.charAt(i-1)) == -1) {
                        i--;
                        if (i == 0) { i = j; break; } // 整行只有單一長單字
                    }
                }
            }

            lastLen = i;
            lines.addElement(temp.substring(0, i));
            if (i == temp.length()) temp = "";
            else {
                temp = temp.substring(i);
                if (temp.startsWith("\n")) temp = temp.substring(1);
            }
        }
    } catch (Exception e) {
        System.out.println("getSubsection: " + e);
    }
    return lines;
}

使用範例

int lineHeight = 15;
int startLine = 0; // 由 keyPressed 控制翻頁

String text = "方便起見,可以定義一個行高作為全局變量...";
Vector lines = getSubsection(text, Font.getDefaultFont(), getWidth(), "");

for (int i = startLine; i < lines.size(); i++) {
    g.drawString((String)lines.elementAt(i), 0, lineHeight * i, Graphics.TOP|Graphics.LEFT);
    if ((i - startLine + 1) * lineHeight > getHeight()) break;
}
lines = null; // 釋放參考

關鍵說明

  • strSplit 傳 " ,.?!" 可避免英文單字被拆半;中文、日文(若不需斷詞)傳空字串。
  • 演算法先以二分搜尋式找寬度邊界,再依 strSplit 回溯至最近分隔字元。
  • 支援手動 \n 強制換行。
  • 回傳 Vector 便於分頁、捲動顯示。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved