構建可組裝、可移植、可維護的 J2ME UI 框架,核心在於將平台差異、視覺規範、佈局參數集中定義為常量類,業務代碼零硬編碼,適配新平台只改常量類。
public class Platform extends Canvas {
// 平台標識常量
public static final byte PLATFORM_SUN_WTK = 10;
public static final byte PLATFORM_NOKIA = 5;
public static final byte PLATFORM_NOKIA_30 = 6; // S40 第3版
public static final byte PLATFORM_SIEMENS = 7;
public static final byte PLATFORM_MOTOROLA = 3;
public static final byte PLATFORM_MOTOROLA_V= 4;
public static final byte PLATFORM_SAMSUNG = 8;
public static final byte PLATFORM_SONYERICSSON=9;
public static final byte PLATFORM_LG = 2;
public static final byte PLATFORM_BARTEO = 1;
// 當前目標平台 (編譯時切換/構建腳本注入)
public static final byte PLATFORM = PLATFORM_SUN_WTK;
// 屏幕尺寸 (運行時動態獲取)
public static int WIDTH;
public static int HEIGHT;
// 雙緩衝支持
public static final boolean DOUBLE_BUFFER = true;
// 統一邏輯鍵碼 (映射到 Canvas 游戲動作)
public static final int KEY_UNDEFINED = 0;
public static final int KEY_UP = -1; // Canvas.UP
public static final int KEY_DOWN = -2; // Canvas.DOWN
public static final int KEY_LEFT = -3; // Canvas.LEFT
public static final int KEY_RIGHT = -4; // Canvas.RIGHT
public static final int KEY_FIRE = -5; // Canvas.FIRE
public static final int KEY_SOFT_LEFT = -6;
public static final int KEY_SOFT_RIGHT = -7;
public static final int KEY_CLEAR = -8;
public static final int KEY_PHONE_ON = -10;
public static final int KEY_PHONE_OFF = -11;
public static final int KEY_ENTER = KEY_FIRE; // 別名
public static final int KEY_FULL_MODE = 48;
public static final int KEY_PAGEUP = 42;
public static final int KEY_PAGEDOWN = 35;
public static final int REFRESH = 53;
// 靜態初始化:啟動全屏 Canvas 獲取真實屏幕尺寸
static {
Canvas dummy = new Canvas() {
protected void paint(Graphics g) {}
protected void sizeChanged(int w, int h) {
if (h > HEIGHT) { WIDTH = w; HEIGHT = h; }
}
};
dummy.setFullScreenMode(true);
if (dummy.getHeight() > HEIGHT) {
WIDTH = dummy.getWidth(); HEIGHT = dummy.getHeight();
}
dummy = null;
}
// 內存工具方法
public static long getTotalMemory() { return Runtime.getRuntime().totalMemory(); }
public static long getFreeMemory() { return Runtime.getRuntime().freeMemory(); }
}
public class Color {
public static final int TRANSPARENT = 0xFFFFFFFF; // 僅 Motorola 支持
public static final int WHITE = 0xFEFEFE;
public static final int DK_GRAY = 0x555555;
public static final int BLACK = 0x000000;
public static final int LT_BLUE = 0xAACCFF; // 补充常用色
public static final int DK_BLUE = 0x0000AA;
// ... 可按需擴展
}
public class Style {
// 字體預定義
public static final Font PLAIN_SMALL = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_SMALL);
public static final Font PLAIN_MEDIUM = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
public static final Font PLAIN_LARGE = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_LARGE);
public static final Font BOLD_SMALL = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_SMALL);
public static final Font BOLD_MEDIUM = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM);
public static final Font BOLD_LARGE = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE);
// 語義化字體引用
public static final Font TEXT_FONT = PLAIN_SMALL;
public static final Font HEADER_FONT = BOLD_SMALL;
public static final Font SOFTKEY_FONT = BOLD_SMALL;
public static final Font TEXT_FIELD_FONT = TEXT_FONT;
// 語義化色值引用
public static final int TEXT_COLOR = Color.BLACK;
public static final int BORDER_COLOR = Color.BLACK;
public static final int FOCUSED_BACKGROUND_COLOR = Color.DK_BLUE;
public static final int FOCUSED_TEXT_COLOR = Color.WHITE;
public static final int CURSOR_TEXT_COLOR = Color.BLACK;
public static final int CURSOR_BACKGROUND_COLOR = Color.WHITE;
public static final int ARROW_COLOR = Color.BLACK;
public static final int TITLE_BACKGROUND_COLOR = Color.LT_BLUE;
public static final int TITLE_TEXT_COLOR = Color.BLACK;
public static final int SOFTKEYBAR_BACKGROUND_COLOR = Color.LT_BLUE;
public static final int SOFTKEYBAR_TEXT_COLOR = Color.BLACK;
// 佈局間距
public static final int V_GAP = 1;
public static final int H_GAP = 1;
public static final int CF_H_GAP = 1;
// 默認背景
public static final int BACKGROUND_COLOR = Color.TRANSPARENT;
// 文本域滾動策略
public static final boolean SCROLLABLE_TEXTFIELD = true;
private Style() {} // 工具類禁止實例化
}
// 繪製標題欄
g.setColor(Style.TITLE_BACKGROUND_COLOR);
g.fillRect(0, 0, Platform.WIDTH, Style.HEADER_FONT.getHeight() + 2*Style.V_GAP);
g.setFont(Style.HEADER_FONT);
g.setColor(Style.TITLE_TEXT_COLOR);
g.drawString(title, Platform.WIDTH/2, Style.V_GAP, Graphics.TOP | Graphics.HCENTER);
// 文本域邊框
g.setColor(Style.BORDER_COLOR);
g.drawRect(x, y, w, h);
if (focused) {
g.setColor(Style.FOCUSED_BACKGROUND_COLOR);
g.fillRect(x+1, y+1, w-2, h-2);
g.setColor(Style.FOCUSED_TEXT_COLOR);
} else {
g.setColor(Style.TEXT_COLOR);
}
Platform、Color、Style 三文件,修改常量值,重新構建。Style 實現 (如 StyleDark、StyleLight),運行時切換引用。Style.*,風格一鍵統一。將「設備差異」封裝在 Platform、「視覺語言」封裝在 Color/Style,業務代碼僅依賴語義化常量,實現了 J2ME UI 框架的高內聚、低耦合、易適配。代碼源自開源項目整理,歡迎按需修改共同完善。