在 J2ME 開發中,掌握 MIDP 用戶界面 API 是構建互動式應用的基石。本文將系統講解 Command 事件機制、TextBox 與 TextField 的輸入差異,以及 Form 容器下的各類 Item 元件(DateField、StringItem、ImageItem、ChoiceGroup、Gauge)的實戰用法,並附帶完整可運行的示例代碼。
J2ME 的事件模型採用「命令-監聽」模式:開發者先定義一系列 Command,再將其註冊到容器(Form、List、TextBox、Alert),最後實現 CommandListener 接口的 commandAction(Command c, Displayable d) 方法統一處理所有命令事件。
Command:指定標籤、類型(BACK、EXIT、OK 等)與優先級。addCommand(Command) 註冊命令。setCommandListener(this) 設置監聽器(通常由 MIDlet 實現)。commandAction 中判斷命令來源並分發處理邏輯。package fancy.test;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class CMD extends MIDlet implements CommandListener {
private Display display;
private Form props;
// 定義八種常用命令
private Command backCommand = new Command("BACK", Command.BACK, 2);
private Command cancelCommand = new Command("CANCEL", Command.CANCEL, 1);
private Command exitCommand = new Command("EXIT", Command.EXIT, 1);
private Command helpCommand = new Command("HELP", Command.HELP, 1);
private Command itemCommand = new Command("ITEM", Command.ITEM, 1);
private Command okCommand = new Command("OK", Command.OK, 1);
private Command screenCommand = new Command("SCREEN", Command.SCREEN, 1);
private Command stopCommand = new Command("STOP", Command.STOP, 1);
public CMD() {
display = Display.getDisplay(this);
}
public void startApp() {
props = new Form("Hello World");
props.append("Hello World!\n");
// 批量註冊命令
props.addCommand(backCommand);
props.addCommand(cancelCommand);
props.addCommand(exitCommand);
props.addCommand(helpCommand);
props.addCommand(itemCommand);
props.addCommand(okCommand);
props.addCommand(screenCommand);
props.addCommand(stopCommand);
props.setCommandListener(this);
display.setCurrent(props);
}
// 輔助方法:彈出新 Form 顯示觸發的命令名
public void showScreen(String cmd) {
Form form = new Form("show cmd");
form.append(cmd);
form.addCommand(exitCommand);
form.setCommandListener(this);
display.setCurrent(form);
}
public void commandAction(Command c, Displayable s) {
if (c == exitCommand) {
destroyApp(false);
notifyDestroyed();
} else if (c == helpCommand) {
showScreen("help");
} else if (c == backCommand) {
showScreen("back");
} else if (c == cancelCommand) {
showScreen("cancel");
} else if (c == itemCommand) {
showScreen("item");
} else if (c == okCommand) {
showScreen("ok");
} else if (c == screenCommand) {
showScreen("screen");
} else if (c == stopCommand) {
showScreen("stop");
}
}
public void destroyApp(boolean unconditional) { }
public void pauseApp() {
display.setCurrent(null);
props = null;
}
}
運行效果:啟動後顯示「Hello World」,按下軟鍵彈出命令菜單,選擇任意命令將彈出新畫面顯示對應命令名稱。
TextBox 是可獨立顯示的容器型組件(繼承 Displayable),適用於多行文本編輯場景。
TextBox(String title, String text, int maxSize, int constraints)
nulltext != null,則必須等於 text.length(),否則運行時拋異常;若 text == null,可任意設定。ANY、EMAILADDR、NUMERIC、PASSWORD 等)public class ShowTextBox extends MIDlet implements CommandListener {
private Display display;
private TextBox txtBox;
private Command exitCommand = new Command("Exit", Command.EXIT, 1);
public ShowTextBox() { display = Display.getDisplay(this); }
public void startApp() {
txtBox = new TextBox("Text Box", null, 200, 0);
txtBox.addCommand(exitCommand);
txtBox.setCommandListener(this);
display.setCurrent(txtBox);
}
// commandAction、destroyApp、pauseApp 省略
}
TextField 屬於 Item 類別,不能單獨顯示,必須添加到 Form 等容器中。適用於表單式單行輸入(如郵箱、電話、密碼)。
TextField(String label, String text, int maxSize, int constraints)
constraints 可選值:TextField.PASSWORD、EMAILADDR、PHONENUMBER、URL、NUMERIC 等。
public class ShowTextField extends MIDlet implements CommandListener {
private Display display;
private Form props;
private TextField txtField;
private Command exitCommand = new Command("Exit", Command.EXIT, 1);
public void startApp() {
props = new Form("Hello World");
props.append("Hello World!\n");
txtField = new TextField("EMail:", "", 15, TextField.EMAILADDR);
props.append(txtField);
props.addCommand(exitCommand);
props.setCommandListener(this);
display.setCurrent(props);
}
// 其他生命周期方法省略
}
同屬 Item,需放入 Form。三種模式:DATE、TIME、DATE_TIME。
DateField dateField = new DateField("Date:", DateField.DATE);
props.append(dateField);
用於在容器中顯示不可編輯的文本,構造函數:StringItem(label, text)。
StringItem item1 = new StringItem("signature:", "小樓一夜聽春雨");
StringItem item2 = new StringItem("signature:", "三教明天考物化");
props.append(item1);
props.append(item2);
三步驟完成圖片嵌入:
Image img = Image.createImage("/fancy/test/JavaPowered-8.png");(圖片需置於 apps/fancy/res 目錄)ImageItem:new ImageItem("Label", img, ImageItem.LAYOUT_DEFAULT, "Alt Text")props.append(imgItem);對齊常量:LAYOUT_DEFAULT、LAYOUT_LEFT、LAYOUT_CENTER、LAYOUT_RIGHT、LAYOUT_NEWLINE_BEFORE、LAYOUT_NEWLINE_AFTER 可組合使用。
項目型組件,對應容器型的 List。構造函數四參數:標籤、類型(EXCLUSIVE 單選 / MULTIPLE 多選)、選項字符串數組、圖標圖片數組(可為 null)。
Image duke = Image.createImage("/fancy/test/Icon.png");
Image[] images = {duke, duke, duke};
String[] options = {"Option A", "Option B", "Option C"};
ChoiceGroup group = new ChoiceGroup("choice group", ChoiceGroup.MULTIPLE, options, images);
props.append(group);
構造函數:Gauge(label, interactive, maxValue, initialValue)。interactive=true 時用戶可拖動調整值。
Gauge gauge = new Gauge("show gauge", true, 100, 50);
props.append(gauge);
本文涵蓋了 MIDP 高級 UI 開發的核心組件:
CommandListener 實現低耦合交互掌握這些組件的構造參數、約束條件與容器關係,即可高效開發符合 J2ME 規範的移動應用界面。