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

Java ME 實戰:基於 GameCanvas 自繪文本編輯框 TextEdit 組件

     編輯:Java 相關知識

在 Java ME(Micro Edition)資源受限環境下,標準高級 UI 的 TextBox 雖功能完整但樣式固定、難以定製。本文展示如何基於 GameCanvas 低級繪圖 API,打造一個自繪、帶閃爍游標、支援彈出系統輸入法的 TextEdit 組件,並整合進用戶註冊頁面實戰演示。

核心設計思路:裝飾器模式 + 系統輸入法代理

  1. 自繪文本框與游標:使用 Graphics.drawString() 繪製文本,drawLine() 繪製游標,通過 clipRect 限制繪製區域防止溢出。
  2. 委託系統 TextBox 輸入:檢測到編輯鍵事件 → 彈出 PopUpTextBox(繼承 TextBox) → 用戶輸入確認 → 回調將字符串回填至 TextEdit。
  3. 游標閃爍動畫:TextEdit 所在 Canvas 實現 Runnable,獨立線程每 500ms 切換游標顯示狀態並重繪。

關鍵類結構

TextEdit          // 核心繪製邏輯:drawTextBox(), drawCursor()
    ↑
UserRegist        // 業務頁面:管理 3 個 TextEdit(用戶名/密碼/確認密碼)
    ↑
PopUpTextBox      // 系統輸入法代理:處理確認/取消回調
    ↑
UIController      // MVC 控制器:事件分發與屏幕切換

核心代碼解析

1. TextEdit 自繪邏輯

public void drawTextBox(GameCanvas canvas, Graphics g, String text,
                        int x, int y, boolean cursorBlinkOn) {
    int padding = 4, margin = 2;
    Font ft = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
    g.setFont(ft);

    // 計算寬高
    width  = 3 * canvas.getWidth() / 5 + 2 * padding;
    height = ft.getHeight() + 2 * padding;

    // 繪製邊框、背景、文本
    g.setColor(Color.frame);
    g.fillRect(x+1, y+1, width+margin, height+margin); // 陰影
    g.setColor(Color.frameBg);
    g.drawRect(x, y, width, height);                   // 邊框
    g.setColor(Color.background);
    g.fillRect(x+1, y+1, width-1, height-1);           // 背景
    g.setColor(Color.text);
    g.drawString(text, x+padding, y+padding, Graphics.TOP|Graphics.LEFT);

    // 繪製游標
    drawCursor(g, x + ft.stringWidth(text) + padding, y+padding,
               1, ft.getHeight(), cursorBlinkOn);

    canvas.flushGraphics(x, y, width, height); // 部分刷新優化
}

2. 游標閃爍線程

// UserRegist 實現 Runnable
public void run() {
    while (true) {
        checkTimeStamp(); // 每 500ms 切換當前編輯框的 cursorBlinkOn
        redraw();         // 重繪三個編輯框
        synchronized(this) { wait(50L); } // 降低 CPU 佔用
    }
}

private void checkTimeStamp() {
    long now = System.currentTimeMillis();
    if (lastCaretBlink + 500 < now) {
        // 僅翻轉當前編輯框的游標狀態
        if ("regist_name".equals(editor)) cursorBlinkOn1 = !cursorBlinkOn1;
        else if ("regist_passwd".equals(editor)) cursorBlinkOn2 = !cursorBlinkOn2;
        else cursorBlinkOn3 = !cursorBlinkOn3;
        lastCaretBlink = now;
    }
}

3. 彈出系統 TextBox 並回填

// UserRegist 按鍵事件
protected void keyPressed(int keyCode) {
    if (keyCode == KEY_EDIT || isNumberKey(keyCode)) {
        Object[] args = {object_name, editor, username, passwd, passwd_re};
        controller.handleEvent(EVENT_USER_REGIST_EDIT, args);
    }
}

// UIController 分發
case EVENT_USER_REGIST_EDIT:
    textBox.init(args);        // 傳遞當前值保持顯示
    midlet.setCurrent(textBox); // 切換到系統 TextBox
    break;

// PopUpTextBox 確認回調
protected void closeTextBox(boolean update) {
    if (update) canvasText = getString(); // 獲取輸入值
    // 根據 editor 字段將值回填到對應參數位置
    Object[] backArgs = {object_name, editor, newUsername, newPasswd, newPasswdRe};
    controller.handleEvent(EVENT_USER_REGIST_EDIT_BACK, backArgs);
}

關鍵技術點總結

擴展建議

  • 增加 最大長度限制、輸入類型過濾(數字/字母/密碼掩碼)。
  • 支援 多行文本:引入 StringDealMethod.format() 自動換行邏輯。
  • 優化 部分刷新:flushGraphics(x,y,w,h) 僅更新編輯區,降低閃屏。
  • 引入 狀態機 管理編輯/正常/禁用狀態,代替分散的 boolean 旗標。

這套 TextEdit 方案在 Java ME 經典項目中經過驗證,兼顧了原生輸入體驗與UI 定製自由度,是資源受限設備上實現富文本交互的實用範本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
挑戰解決方案
低級 UI 無輸入法委託高級 TextBox,裝飾器模式無縫切換
多編輯框游標管理獨立 boolean 旗標 + 單線程定時器輪詢
文本不換行截斷clipRect 限制繪製區 + stringWidth 計算游標位置
屏幕適配寬高按 canvas.getWidth()/Height() 比例動態計算
數據同步彈出前帶走舊值,確認後回調覆蓋,取消則丟棄