You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Eclipse RCP应用中新增References标签页展示搜索结果

问题描述

我开发了一个基于Eclipse RCP的应用,已实现一个Handler,可搜索指定内容并在Eclipse内置的Search标签页展示结果,Handler代码如下:

public class ReferencesSearchHandler extends AbstractHandler {
    @Override
    public Object execute(ExecutionEvent event) throws ExecutionException {
        IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
        if (window != null) {
            IStructuredSelection selection = HandlerUtil.getCurrentStructuredSelection(event);
            if (selection != null && !selection.isEmpty()) {
                Object firstElement = selection.getFirstElement();
                if (firstElement instanceof IFile) {
                    IFile file = (IFile) firstElement;
                    IPath path = file.getFullPath();
                    String[] segments = path.segments();
                    String fileNameWithExtension = file.getName();
                    String fileNameWithoutExtension = removeFileExtension(fileNameWithExtension);
                    String searchText = createSearchText(segments, fileNameWithoutExtension);
                    performSearch(searchText);
                }
            }
        }
        return null;
    }

    private String createSearchText(String[] segments, String fileNameWithoutExtension) {
        String packageName = segments[2];
        int i = 3;
        int n = segments.length - 1;
        for (i = 3; i < n; i++) {
            packageName = packageName + "." + segments[i];
        }

        return packageName + "." + fileNameWithoutExtension;
    }

    private String removeFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex > 0) {
            return fileName.substring(0, lastDotIndex);
        }
        return fileName;
    }

    private void performSearch(String projectName) {
        FileTextSearchScope scope = createWorkspaceScope();
        NewSearchUI.runQueryInBackground(new FileSearchQuery(projectName, false, false, scope));
    }

    private FileTextSearchScope createWorkspaceScope() {
        IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
        IResource[] resources = new IResource[projects.length];
        for (int i = 0; i < projects.length; i++) {
            resources[i] = projects[i];
        }
        return FileTextSearchScope.newSearchScope(resources, new String[] { "*" }, false);
    }

}

现在我不想在Search标签页展示搜索结果,希望新建一个名为References的标签页来展示该结果,请问是否可行?若可行该如何实现?

解决方案

完全可行,核心思路是自定义专属视图展示搜索结果,替代默认的Search视图。具体实现分四步:

1. 创建自定义References视图类

继承ViewPart,使用TableViewer展示搜索结果(也可根据需求替换为TreeViewer),示例代码:

public class ReferencesView extends ViewPart {
    public static final String VIEW_ID = "com.your.plugin.id.views.ReferencesView"; // 替换为你的插件ID
    private TableViewer viewer;

    @Override
    public void createPartControl(Composite parent) {
        viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
        viewer.setContentProvider(ArrayContentProvider.getInstance());
        
        // 配置表格列,展示文件名、路径、匹配行号
        TableColumn fileNameCol = new TableColumn(viewer.getTable(), SWT.NONE);
        fileNameCol.setText("文件名");
        fileNameCol.setWidth(200);
        
        TableColumn pathCol = new TableColumn(viewer.getTable(), SWT.NONE);
        pathCol.setText("路径");
        pathCol.setWidth(400);
        
        TableColumn lineCol = new TableColumn(viewer.getTable(), SWT.NONE);
        lineCol.setText("行号");
        lineCol.setWidth(100);
        
        viewer.getTable().setHeaderVisible(true);
        viewer.getTable().setLinesVisible(true);
        
        // 设置标签提供者,定义每列显示内容
        viewer.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getColumnText(Object element, int columnIndex) {
                if (element instanceof FileSearchMatch) {
                    FileSearchMatch match = (FileSearchMatch) element;
                    switch (columnIndex) {
                        case 0:
                            return match.getFile().getName();
                        case 1:
                            return match.getFile().getFullPath().toString();
                        case 2:
                            return String.valueOf(match.getLineNumber());
                        default:
                            return "";
                    }
                }
                return "";
            }
        });
    }

    @Override
    public void setFocus() {
        viewer.getControl().setFocus();
    }

    // 供Handler调用的结果更新方法
    public void updateSearchResults(List<FileSearchMatch> matches) {
        viewer.setInput(matches.toArray());
    }
}

2. 在plugin.xml中注册自定义视图

添加org.eclipse.ui.views扩展,声明References视图:

<extension
      point="org.eclipse.ui.views">
   <category
         name="自定义视图"
         id="com.your.plugin.id.views.category">
   </category>
   <view
         name="References"
         icon="icons/references_icon.png" <!-- 可选,添加视图图标 -->
         category="com.your.plugin.id.views.category"
         class="com.your.plugin.id.views.ReferencesView"
         id="com.your.plugin.id.views.ReferencesView">
   </view>
</extension>

注意替换所有com.your.plugin.id为你实际的插件ID。

3. 修改Handler的搜索执行逻辑

不再依赖NewSearchUI的默认展示,改为手动执行查询并将结果传递到自定义视图。修改performSearch方法:

private void performSearch(String searchText) {
    FileTextSearchScope scope = createWorkspaceScope();
    FileSearchQuery query = new FileSearchQuery(searchText, false, false, scope);
    
    // 后台执行搜索,避免阻塞UI
    Job searchJob = new Job("搜索引用") {
        @Override
        protected IStatus run(IProgressMonitor monitor) {
            try {
                IQueryResult result = query.run(monitor);
                if (result instanceof FileSearchResult) {
                    FileSearchResult searchResult = (FileSearchResult) result;
                    List<FileSearchMatch> matches = new ArrayList<>();
                    
                    // 遍历所有搜索结果
                    for (Object element : searchResult.getElements()) {
                        if (element instanceof IFile) {
                            IFile file = (IFile) element;
                            Iterator<?> matchIterator = searchResult.getMatches(element);
                            while (matchIterator.hasNext()) {
                                Object matchObj = matchIterator.next();
                                if (matchObj instanceof FileSearchMatch) {
                                    matches.add((FileSearchMatch) matchObj);
                                }
                            }
                        }
                    }
                    
                    // 在UI线程更新视图
                    Display.getDefault().asyncExec(() -> {
                        try {
                            IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
                            ReferencesView view = (ReferencesView) page.showView(ReferencesView.VIEW_ID);
                            view.updateSearchResults(matches);
                        } catch (PartInitException e) {
                            e.printStackTrace();
                        }
                    });
                }
            } catch (CoreException e) {
                e.printStackTrace();
                return new Status(IStatus.ERROR, "com.your.plugin.id", "搜索失败", e);
            }
            return Status.OK_STATUS;
        }
    };
    searchJob.schedule();
}

4. 测试效果

运行RCP应用,触发Handler的搜索操作后,Eclipse会自动打开References标签页并展示搜索结果。

内容的提问来源于stack exchange,提问作者Satya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:07:08