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

Eclipse TreeViewer 組件深度解析:從核心 API 到檔案瀏覽器實戰

     編輯:Java 相關知識

TreeViewer 是 Eclipse JFace 提供的強大樹形檢視組件,採用「內容提供器」與「標籤提供器」分離模型,靈活構建樹狀結構並控制節點顯示。本文將系統拆解其構建步驟、核心介面實作細節,並通過完整檔案瀏覽器範例演示實戰應用。

TreeViewer 四步構建法

  1. 建立實例:TreeViewer tv = new TreeViewer(composite);
  2. 設定內容提供器:tv.setContentProvider(new FileTreeContentProvider());
  3. 設定標籤提供器:tv.setLabelProvider(new FileTreeLabelProvider());
  4. 輸入資料模型:tv.setInput("root");(輸入物件將傳遞給內容提供器的 getElements 方法)

核心介面:ITreeContentProvider 詳解

內容提供器負責樹的資料結構與層級關係,需實作以下關鍵方法:

1. getElements(Object inputElement)

樹構建起始點,回傳根節點陣列。inputElement 即 setInput 傳入的物件。

2. hasChildren(Object element)

判斷節點是否有子節點,回傳 true 時節點顯示展開圖示(+)。

3. getChildren(Object parentElement)

使用者展開節點時呼叫,回傳該節點的直接子節點陣列。

4. getParent(Object element)

回傳指定節點的父節點,支援向上導航。

5. inputChanged(Viewer viewer, Object oldInput, Object newInput)

輸入模型變更時觸發,可在此更新內部狀態或註冊監聽器。

6. dispose()

Viewer 銷毀時呼叫,釋放資源(如取消監聽、關閉連線)。

實作重點:getElements、hasChildren、getChildren 是構建樹的三大核心。流程為:取得根 → 判斷是否有子節點 → 遞迴取得子節點。

範例:檔案系統內容提供器

class FileTreeContentProvider implements ITreeContentProvider {
    public Object[] getChildren(Object arg0) {
        return ((File) arg0).listFiles(); // 返回目錄下檔案/子目錄
    }
    public Object getParent(Object arg0) {
        return ((File) arg0).getParentFile(); // 返回父目錄
    }
    public boolean hasChildren(Object arg0) {
        Object[] obj = getChildren(arg0);
        return obj != null && obj.length > 0; // 有子節點顯示 "+"
    }
    public Object[] getElements(Object arg0) {
        System.out.println(arg0); // 輸入通常為 "root"
        return File.listRoots(); // 以磁碟根目錄作為樹的根節點
    }
    public void dispose() {}
    public void inputChanged(Viewer v, Object old, Object nw) {}
}

標籤提供器:ILabelProvider 控制顯示

決定節點的文字與圖示。核心方法:

  • getText(Object obj):回傳節點顯示文字。
  • getImage(Object obj):回傳節點圖示(Image 物件)。

範例:檔案/目錄圖示與大小寫切換

class FileTreeLabelProvider implements ILabelProvider {
    private List listeners = new ArrayList();
    private Image fileImg, dirImg;
    boolean preserveCase;

    public FileTreeLabelProvider() {
        try {
            fileImg = new Image(null, new FileInputStream("icons/file.gif"));
            dirImg = new Image(null, new FileInputStream("icons/directory.gif"));
        } catch (FileNotFoundException e) {}
    }

    public Image getImage(Object obj) {
        return ((File) obj).isDirectory() ? dirImg : fileImg;
    }

    public String getText(Object obj) {
        String text = ((File) obj).getName();
        if (text.length() == 0) text = ((File) obj).getPath();
        return preserveCase ? text : text.toUpperCase(); // 依核取方塊決定大小寫
    }

    // 標準監聽器管理與 dispose 略...
    public void setPreserveCase(boolean preserveCase) {
        this.preserveCase = preserveCase;
        fireLabelProviderChanged(new LabelProviderChangedEvent(this));
    }
}

完整實戰:檔案瀏覽器 TreeViewer

整合上述提供器,建立可切換大小寫的檔案樹視窗。

public class FileBrowserTreeViewer extends ApplicationWindow {
    public FileBrowserTreeViewer() { super(null); }

    public void run() {
        setBlockOnOpen(true);
        open();
        Display.getCurrent().dispose();
    }

    protected void configureShell(Shell shell) {
        super.configureShell(shell);
        shell.setText("File Tree");
        shell.setSize(400, 400);
    }

    protected Control createContents(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new GridLayout(1, false));

        Button preserveCase = new Button(composite, SWT.CHECK);
        preserveCase.setText("&Preserve case");

        final TreeViewer tv = new TreeViewer(composite);
        tv.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));

        tv.setContentProvider(new FileTreeContentProvider());
        tv.setLabelProvider(new FileTreeLabelProvider());
        tv.setInput("root");

        preserveCase.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                boolean preserve = ((Button) e.widget).getSelection();
                FileTreeLabelProvider ftlp = (FileTreeLabelProvider) tv.getLabelProvider();
                ftlp.setPreserveCase(preserve);
            }
        });
        return composite;
    }

    public static void main(String[] args) {
        new FileBrowserTreeViewer().run();
    }
    // 內部類 FileTreeContentProvider、FileTreeLabelProvider 同前...
}

執行效果:視窗左側顯示磁碟根目錄樹,右側核取方塊控制節點文字大小寫。注意:範例中 icons/file.gif 與 icons/directory.gif 需自行放置於專案根目錄下的 icons 資料夾。

總結

TreeViewer 以 MVC 分離設計,將資料模型(內容提供器)與視覺表現(標籤提供器)解耦,支援複雜樹結構的高效渲染與動態更新。掌握 ITreeContentProvider 三大核心方法與 ILabelProvider 雙方法,即可構建從簡單目錄樹到複雜領域模型的各類樹形介面。

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