如何通过Eclipse JDT的FilteredTypesSelectionDialog筛选实现指定接口的类?
使用Eclipse JDT的FilteredTypesSelectionDialog筛选实现特定接口的类
当然有可行的实现方式!我之前在处理类似需求的时候,就是通过给FilteredTypesSelectionDialog添加自定义类型过滤器来实现的,核心思路是利用JDT提供的ITypeFilter接口,在过滤器中判断类是否实现了目标接口。
具体实现步骤
- 获取目标接口的
IType对象:首先要定位到你要筛选的那个接口,确保它在当前工作区的Java项目中存在。 - 自定义
ITypeFilter实现:在过滤器的select方法中编写逻辑,判断当前类是否直接或间接实现了目标接口。 - 将过滤器绑定到对话框:把自定义过滤器设置到
FilteredTypesSelectionDialog中,然后打开对话框即可。
完整代码片段
import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.ui.dialogs.FilteredTypesSelectionDialog; import org.eclipse.jdt.ui.dialogs.ITypeFilter; import org.eclipse.swt.widgets.Shell; import org.eclipse.jface.window.Window; // 假设你已经获取了当前的JavaProject和Shell对象 IJavaProject javaProject = ...; Shell shell = ...; // 步骤1:获取目标接口的IType(这里以com.example.MyInterface为例) String targetInterfaceName = "com.example.MyInterface"; IType targetInterface = null; try { targetInterface = javaProject.findType(targetInterfaceName); } catch (JavaModelException e) { e.printStackTrace(); } if (targetInterface == null) { // 处理接口不存在的情况,比如弹出提示 return; } // 步骤2:创建自定义类型过滤器 ITypeFilter interfaceImplFilter = new ITypeFilter() { @Override public boolean select(IType type) { try { // 只处理类,排除接口、枚举等其他类型 if (!type.isClass()) { return false; } // 检查当前类直接实现的接口 IType[] directInterfaces = type.getSuperInterfaceTypes(); for (IType iface : directInterfaces) { if (iface.getFullyQualifiedName().equals(targetInterface.getFullyQualifiedName())) { return true; } // 递归检查父接口(如果需要筛选间接实现的类) if (checkSuperInterfaceRecursively(iface, targetInterface)) { return true; } } // 可选:检查父类是否实现了目标接口(如果需要筛选继承自实现类的子类) IType superClass = type.getSuperclassType(); if (superClass != null) { return checkSuperInterfaceRecursively(superClass, targetInterface); } } catch (JavaModelException e) { e.printStackTrace(); } return false; } // 递归检查父接口的辅助方法 private boolean checkSuperInterfaceRecursively(IType currentType, IType target) throws JavaModelException { if (currentType.isInterface()) { IType[] superInterfaces = currentType.getSuperInterfaceTypes(); for (IType iface : superInterfaces) { if (iface.getFullyQualifiedName().equals(target.getFullyQualifiedName())) { return true; } if (checkSuperInterfaceRecursively(iface, target)) { return true; } } } else if (currentType.isClass()) { // 检查父类实现的接口 IType[] superInterfaces = currentType.getSuperInterfaceTypes(); for (IType iface : superInterfaces) { if (iface.getFullyQualifiedName().equals(target.getFullyQualifiedName())) { return true; } if (checkSuperInterfaceRecursively(iface, target)) { return true; } } // 继续递归检查父类的父类 IType superClass = currentType.getSuperclassType(); if (superClass != null) { return checkSuperInterfaceRecursively(superClass, target); } } return false; } }; // 步骤3:初始化对话框并设置过滤器 IJavaElement[] scopeElements = new IJavaElement[] { javaProject }; var searchScope = SearchEngine.createJavaSearchScope(scopeElements); var dialog = new FilteredTypesSelectionDialog(shell, false, null, searchScope, IJavaSearchConstants.CLASS); // 绑定自定义过滤器 dialog.setTypeFilters(new ITypeFilter[] { interfaceImplFilter }); // 自定义对话框提示 dialog.setTitle("Select Classes Implementing " + targetInterfaceName); dialog.setMessage("Choose a class that implements the target interface"); // 打开对话框并处理选中结果 if (dialog.open() == Window.OK) { Object[] results = dialog.getResult(); if (results != null && results.length > 0) { IType selectedClass = (IType) results[0]; // 这里可以添加对选中类的后续处理逻辑 System.out.println("Selected class: " + selectedClass.getFullyQualifiedName()); } }
额外说明
- 如果只需要筛选直接实现目标接口的类,可以去掉递归检查父接口和父类的逻辑,简化代码。
- 注意处理
JavaModelException,这是JDT操作中常见的异常,建议根据实际场景添加日志或用户提示。 - 可以修改过滤器逻辑,支持同时筛选多个接口的实现类。
内容的提问来源于stack exchange,提问作者Vishal Pawar
相关产品推荐
相关产品推荐

