基於事件觸發模型的程式設計,能在有限程度上提升程式的靈活性與擴展性,將具體程式碼的依賴關係延遲至觸發時刻才實現。然而在 J2ME 環境下,無法使用委派等語法,平台本身也缺乏完善的事件系統。網路上關於 J2ME 事件處理的資料,多半僅止於介紹 Command 與 CommandListener,鮮少提及自訂事件框架的實作。
實作 CommandListener 介面的類別,可透過 Displayable 子類別的引用來接收事件回呼:
public class Test implements CommandListener {
public void commandAction(Command c, Displayable d) {
// 處理命令事件
}
}
// 使用方式
Displayable.setCommandListener(new Test());
為彌補平台不足,我設計了一個簡易的事件框架 HEvent,核心原理是利用索引管理監聽器,避免複雜的查詢開銷,確保執行效率。
package hlib;
import java.util.Vector;
public class HEvent {
private static Vector listeners = new Vector();
public interface HEventListener {
void eventAction(int eventListenerHandle, int eventType, Object param);
}
// 註冊監聽器,回傳 handle(索引+1)
public static int setHEventListener(HEventListener listener) {
listeners.addElement(listener);
return listeners.size();
}
// 建立監聽器群組
public static Vector setNewGroup(int[] listenerIndexs) {
Vector newGroup = new Vector();
for (int i = 0; i < listenerIndexs.length; i++) {
newGroup.addElement(new Integer(listenerIndexs[i]));
}
return newGroup;
}
// 單一監聽器發布事件
public static void publish(int eventListenerHandle, int eventType, Object param) {
if (eventListenerHandle > 0 && eventListenerHandle <= listeners.size()) {
((HEventListener) listeners.elementAt(eventListenerHandle - 1))
.eventAction(eventListenerHandle, eventType, param);
} else {
throw new IndexOutOfBoundsException();
}
}
// 群組發布事件(循序執行)
public static void publish(Vector group, int eventType, Object param) {
for (int i = 0; i < group.size(); i++) {
publish(((Integer) group.elementAt(i)).intValue(), eventType, param);
}
}
}
HEventListener 介面;發布者需註冊發布 ID (eventListenerHandle) 並定義事件類型 (eventType)。eventAction 中的 eventListenerHandle 參數,用於單一監聽器對應多個發布者的情境。setNewGroup 與 publish(Vector, ...) 實現群組發布(循序執行)。// 發布者
public class Publisher {
public static final int EVENT_1 = 1;
public static final int EVENT_2 = 2;
private int eventListenerHandle;
public Publisher(int eventListenerHandle) {
this.eventListenerHandle = eventListenerHandle;
}
public void fun1() {
HEvent.publish(eventListenerHandle, EVENT_1, null);
}
public void fun2() {
Object param = new Object();
HEvent.publish(eventListenerHandle, EVENT_2, param);
}
}
// 監聽者
public class EventListener implements HEvent.HEventListener {
public void eventAction(int eventListenerHandle, int eventType, Object param) {
// 依 eventType 分派處理
}
}
有了事件處理機制,J2ME 開發變得更加靈活愉快!