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

J2ME 實現可伸展目錄樹 TreeList 組件

     編輯:J2ME

前言

J2ME 內建的 List 類功能較弱,未實現 View 與 Model 的分離,導致控制較為繁瑣。若自行繪製 Canvas 版 TreeList 則需大量座標計算,開發難度高。本文介紹一種折衷方案:繼承 List 類,封裝資料模型,實現一個易於控制、支援兩層展開收合的目錄樹組件。

設計目標

  • 可伸縮的目錄樹結構(示範兩層)
  • 標籤與存儲內容分離
  • 支援選中/未選中狀態的圖示切換
  • 透過選擇事件快速定位對應資料
  • 內容物件無關性,可存放任意 Object

核心類設計

ExpandListItem - 資料節點封裝

每個節點資料包含:預設圖示路徑、選中狀態圖示路徑、節點類型(GROUP/ITEM)、顯示標籤、攜帶的任意物件內容、是否展開狀態。

public class ExpandListItem {
    private String imagePath = "";
    private String selectImgPath = null;
    public static final int GROUP = 1;
    public static final int ITEM = 0;
    private boolean ifselected = false;
    private String label;
    private int type;
    private Object content;
    // getter/setter 略
}

說明:GROUP 代表父節點,其 content 為包含子節點的 Vector;ITEM 為葉子節點。selectImgPath 為空時選中不切換圖示。

ExpandList - 目錄樹主控制類

繼承自 List,實現 CommandListener。核心資料結構:

  • itemList:真實資料儲存 Vector
  • appearHookList:螢幕顯示順序的節點列表(含展開的子節點)
  • currentSelectedIndex / currentSelectedObject:當前選中項索引與物件

關鍵邏輯:LoadList() 重繪機制

public void LoadList() {
    Init(); // 清空顯示列表
    for (int i = 0; i < itemList.size(); i++) {
        ExpandListItem elItem = (ExpandListItem) itemList.elementAt(i);
        if (elItem.getType() == ExpandListItem.GROUP) {
            Image icon = Util.getImage(elItem.getImagePath());
            if (elItem.Ifselected()) { // 展開狀態
                if (elItem.getSelectImgPath() != null) 
                    icon = Util.getImage(elItem.getSelectImgPath());
                appendItem(elItem, icon, false); // 父節點
                Vector group = (Vector) elItem.getContent();
                for (int j = 0; j < group.size(); j++) { // 遞歸添加子節點
                    ExpandListItem item = (ExpandListItem) group.elementAt(j);
                    appendItem(item, Util.getImage(item.getImagePath()), true);
                }
            } else { // 收合狀態僅顯示父節點
                appendItem(elItem, icon, false);
            }
        } else { // ITEM 類型
            appendItem(elItem, Util.getImage(elItem.getImagePath()), false);
        }
    }
    if (currentSelectedIndex != -1) 
        setSelectedIndex(currentSelectedIndex, true);
}

選擇事件處理 commandAction()

使用者點選節點時:

  1. 取得 appearHookList 中的實際物件與在 itemList 中的索引
  2. 父節點 (GROUP):切換 ifselected 狀態,移除並重新插入 itemList 觸發 LoadList() 全量重繪
  3. 子節點 (ITEM):若有選中圖示則切換圖示並局部更新該行

測試範例

Vector v = new Vector();
v.addElement(new ExpandListItem(subVector1, "/img/close.png", "/img/open.png", "群組A", ExpandListItem.GROUP, false));
v.addElement(new ExpandListItem(subVector2, "/img/close.png", "/img/open.png", "群組B", ExpandListItem.GROUP, false));
v.addElement(new ExpandListItem("單項內容", "/img/item.png", null, "單項", ExpandListItem.ITEM, false));
Display.getDisplay(this).setCurrent(new ExpandList("標題", Choice.IMPLICIT, v));

總結與展望

此方案利用 List 現有繪製機制,以資料驅動視圖更新,避免了 Canvas 座標計算的複雜度。雖全量重繪在大量資料時效率稍低,但對於典型手機選單層級足夠使用。未來可優化為局部插入/刪除子節點,進一步提升效能。最徹底的方案仍是自繪 Canvas,靈活度最高。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved