在 MIDP 低階 Canvas 開發中,Graphics.drawString() 並不支援自動換行。當需在有限螢幕寬度顯示長字串(如對話框、說明文字)時,必須自行實作「按像素寬度斷行」的邏輯。
Font 實例。font.charWidth())。getWidth() - padding),將目前累積的子字串存入 Vector,重置累計寬度與起始索引。Vector。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[],並支援對齊方式(左/中/右)、行間距、縮排等參數,即可在專案中複用於選單、說明頁、聊天氣泡等多種場景。