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

Eclipse Navigator Link Helper 實現:導航器與編輯器雙向聯動完整指南

     編輯:Java 相關知識

Link Helper 核心作用

實現編輯器與導航器視圖雙向同步選中:
• 編輯器切換文件 → 導航器自動定位並選中對應節點
• 導航器點擊節點 → 編輯器打開/切換到對應文件

基於 CNF (Common Navigator Framework) 的兩種實現層次

第一層:直接復用 IResource(簡單場景)

無需寫 Java 代碼,通過 navigatorContent 復用 Project Explorer 行為。但業務模型若非簡單文件樹(如 Java Package 合並顯示、JAR 內部結構),則需自定義模型層。

第二層:自定義業務模型層(本文重點)

優勢:
• UI 操作先更新域模型,再持久化到 IResource,邏輯更清晰
• 同一資源可構建多種視角(Package Explorer vs Resource Explorer)

虛擬模型層設計

Eclipse 資源管理 虛擬模型類圖

// 核心接口
public abstract class VirtualNode {
    protected IResource resource; // 關聯底層資源
    protected VirtualNode parent; // 父節點,關鍵:支撐向上回溯
    public static final int PROJECT=1, FOLDER=2, FILE=3;
    public abstract Image getImage();
    public String getText() { return resource.getName(); }
    // getter/setter
}

// 三種具體節點
public class ProjectNode extends VirtualNode { ... }
public class FolderNode extends VirtualNode { ... }
public class FileNode extends VirtualNode { ... }

LabelProvider 與 ContentProvider

LabelProvider:多態顯示

public class MyCustomLabelProvider extends LabelProvider {
    public Image getImage(Object element) {
        return element instanceof VirtualNode ? ((VirtualNode)element).getImage() : super.getImage(element);
    }
    public String getText(Object element) {
        return element instanceof VirtualNode ? ((VirtualNode)element).getText() : super.getText(element);
    }
}

ContentProvider:樹構建 + 節點註冊映射

public class MyCustomContentProvider extends ... {
    // 關鍵:IResource → VirtualNode 映射表,支撐 Link Helper 反向查找
    private Map resources2NodesMap = new HashMap<>();

    public Object[] getChildren(Object element) {
        List children = new ArrayList<>();
        if (element instanceof IWorkspaceRoot) {
            // 根節點 → 專案節點
        } else if (element instanceof VirtualNode) {
            // 虛擬節點 → 子文件夾/文件節點
            // 過濾 . 開頭隱藏文件
            // 創建並 register 到 map
        }
        return children.toArray();
    }

    // hasChildren 避免過早註冊 N+1 級節點
    private boolean register = true;
    public boolean hasChildren(Object element) {
        register = false;
        boolean flag = super.hasChildren(element);
        register = true;
        return flag;
    }
}

Link Helper 核心實現

public class MyLinkHelper implements ILinkHelper {
    public IStructuredSelection findSelection(IEditorInput input) {
        IFile file = ResourceUtil.getFile(input);
        if (file == null) return StructuredSelection.EMPTY;

        VirtualNode node = MyCustomContentProvider.INSTANCE.getResources2NodesMap().get(file);
        if (node == null) {
            // 地圖未初始化,模擬樹展開路徑構建映射
            IProject project = file.getProject();
            // 1. 展開專案節點
            getChildren(resources2NodesMap.get(project));
            // 2. 逐層向上收集父資源入棧
            Stack stack = new Stack<>();
            IResource parent = file.getParent();
            while (parent != project) { stack.push(parent); parent = parent.getParent(); }
            // 3. 逐層出棧展開
            while (!stack.isEmpty()) { getChildren(resources2NodesMap.get(stack.pop())); }
            // 4. 獲取最終節點
            node = resources2NodesMap.get(file);
        }
        return node != null ? new StructuredSelection(node) : StructuredSelection.EMPTY;
    }

    public void activateEditor(IWorkbenchPage page, IStructuredSelection selection) {
        if (selection.getFirstElement() instanceof FileNode) {
            IFile file = ((FileNode)selection.getFirstElement()).getResource();
            IEditorInput input = new FileEditorInput(file);
            IEditorPart editor = page.findEditor(input);
            if (editor != null) page.bringToTop(editor);
        }
    }
}

plugin.xml 關鍵配置

plugin.xml 配置

運行效果驗證

準備文件 編輯器導航器聯動

應用場景擴展

  • Ctrl+Shift+R/T 打開文件後自動定位導航器
  • 拖拽導航器節點到編輯器區自動定位
  • 源碼閱讀時快速定位包結構

總結

Link With Editor 實現需理解 CNF 框架設計,核心在於業務模型與 IResource 的雙向映射表,配合父節點引用支撐樹路徑回溯。掌握此模式,可為任何自定義導航器添加專業級聯動體驗。

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