如何在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
相关产品推荐
相关产品推荐

