Java EclipsePDE、Navigator视图、TreeSelection-获取文件类型和名称

Java EclipsePDE、Navigator视图、TreeSelection-获取文件类型和名称,java,eclipse,eclipse-plugin,eclipse-rcp,eclipse-pde,Java,Eclipse,Eclipse Plugin,Eclipse Rcp,Eclipse Pde,我试图在Navigator树视图中获取Eclipse用户结构化选择的详细信息。目前,我有以下基于org.eclipse.ui.popMenus扩展点的内容: public void run(IAction action) { Shell shell = new Shell(); ISelection selection = workbenchPart.getSite().getSelectionProvider().getSelection(); if (structuredSelecti

我试图在Navigator树视图中获取Eclipse用户结构化选择的详细信息。目前,我有以下基于org.eclipse.ui.popMenus扩展点的内容:

public void run(IAction action) {

Shell shell = new Shell();

ISelection selection = workbenchPart.getSite().getSelectionProvider().getSelection();

if (structuredSelection instanceof org.eclipse.jface.viewers.TreeSelection) {

   org.eclipse.jface.viewers.TreeSelection treeSelection = (org.eclipse.jface.viewers.TreeSelection) structuredSelection;
   IAdaptable firstElement = (IAdaptable) treeSelection.getFirstElement();

   // Relies on an internal API, bad juju
   if (firstElement instanceof org.eclipse.jdt.internal.core.CompilationUnit) {
    org.eclipse.jdt.internal.core.CompilationUnit compilationUnit = (org.eclipse.jdt.internal.core.CompilationUnit) firstElement;                                   
    String editorSelection = new String(compilationUnit.getContents());
   }            
}
问题是,它当前与JDT编译单元API耦合,后者是内部的,对于我想要的内容来说太具体了


理想情况下,我希望能够获得底层文件名、类型和内容,而无需依赖:

  • 内部API
  • JDT编译单元代码 这样,当用户在navigator视图中右键单击一个文件时,我就可以获得一个通用文件的属性


    有没有人能给我一些建议,告诉我如何做这件事?

    你想达到什么目的?是否要获取文件内容?然后您可以尝试:

    IAdaptable firstElement = (IAdaptable) treeSelection.getFirstElement();
    
    IFile file = (IFile) firstElement.getAdapter(IFile.class);
    if (file != null && file.isAccessible()) {
        // Use getContents API
        ....
    }
    

    [编辑:我添加了以下备选方案-最初的答案是父亲下台]

    第一:如果您在PackageExplorer中选择了一些东西,那么所选的项目都是Java模型对象——您必须在某种程度上处理它们。有两种方法可以处理此问题:

  • 直接使用ICompilationUnit(请参阅下文)
  • 创建Eclipe适配器工厂以自动转换
  • 适配器工厂方法 您可以创建一个适配器工厂(它可以存在于您的主插件或其他插件中),eclipse可以使用它自动将ICompilationUnit转换为IFile

    注意:如果您在不同的插件中创建适配器工厂,您可能需要为其设置早期启动,以加载适配器工厂。否则,您需要让您的插件与选择一起工作,这取决于提供适配器的插件

    上有一些关于适配器的详细信息,但我将在这里介绍这个问题的实现

    依赖关系 将承载适配器的插件需要以下依赖项

    • org.eclispe.core.resources
    • org.eclipse.jdt.core
    适配器工厂类 在新插件中定义以下类

    package com.javadude.foo;
    
    import org.eclipse.core.resources.IFile;
    import org.eclipse.core.runtime.IAdapterFactory;
    import org.eclipse.jdt.core.ICompilationUnit;
    
    public class CompilationUnitToFileAdapter implements IAdapterFactory {
        @Override
        public Object getAdapter(Object adaptableObject, Class adapterType) {
            if (adaptableObject instanceof ICompilationUnit)
                // note: "adapting" it here just means returning the ref'd IFile
                return (IFile) ((ICompilationUnit)adaptableObject).getResource();
            return null;
        }
        @Override
        public Class[] getAdapterList() {
            return new Class[] {IFile.class};
        }
    }
    
    分机 在将承载适配器工厂的插件中,将以下内容添加到plugin.xml中:

    <extension point="org.eclipse.core.runtime.adapters">
        <factory
            adaptableType="org.eclipse.jdt.core.ICompilationUnit"
            class="com.javadude.foo.AdapterFactory1">
            <adapter type="org.eclipse.core.resources.IFile" />
        </factory>
    </extension>
    
    使用这种方法,您可以添加额外的适配器来将其他类型转换为IFile,而您的选择代码并不在意


    直接ICompilationUnit方法 [编辑:我已更改答案,但将以下内容保留为参考信息b/c这是探索在package explorer中选择的编译单元内容的标准方法]

    这实际上是在包资源管理器中获取文件内容的首选方法

    您应该使用ICompilationUnit,而不是使用CompilationUnit。大多数EclipseAPI使用接口用于公共消费,使用类用于内部细节

    如果您将代码更改为

    if (firstElement instanceof ICompilationUnit) {
        ICompilationUnit unit = (ICompilationUnit firstElement;
        String contents = new String(unit.getContents());
    }
    
    你的身体会很好的

    要查看检查/修改Java模型和源代码的详细信息,请执行以下操作:

    (In Eclipse)
    Help->
      Help Contents->
        JDT Plug-in Developer's Guide->
          Programmer's Guide->
            JDT Core
    
    这说明了如何适当地使用Java模型

    要隔离引用java模型的位置,可以创建一个(eclipse)适配器,将java模型对象转换为文件。假设存在这样一个适配器,那么您可以要求AdapterManager将其转换为java文件。我将浏览一下,看看是否存在这样一个问题。

    这(将资源与JDT分离)是的目标之一。
    不再提及JDT(同样,仅限Eclipse4.x):

    • org.eclipse.core.filesystem
      ——一种抽象的通用文件系统API,包括用于本地文件系统的此API的实现。这是资源插件访问底层文件系统的API
    • org.eclipse.core.resources
      -包含资源模型的API和实现
    • org.eclipse.core.resources.compatibility
      ——为在eclipse 3.1或更高版本中打开旧工作区的用户提供迁移支持的插件
    像这样的演示项目不需要任何JDT

    void setSelection(@Named(IServiceConstants.ACTIVE_选择)
    i资源选择){
    ...
    IResource[]members=input.members();
    ...
    IResource资源=成员[i];
    if(resource.getType()==IResource.FILE){
    InputStream内容=((IFile)资源).getContents();
    
    看来JDT已经为所有Java元素(包括编译单元(
    org.eclipse.JDT.internal.ui.JavaElementAdapterFactory
    )定义了一个
    IAdapterFactory
    )。适配器是为
    IResource
    定义的,而不是为
    IFile
    定义的,因此您应该能够:

    Object firstElement = treeSelection.getFirstElement();
    
    IResource resource = (IResource)Platform.getAdapterManager().getAdapter(firstElement, IResource.class);
    

    当然,但是:这个接口不打算由客户端实现。你没有实现它;你正在使用它作为实现的句柄。这是预期的用法。查看文档页面(请删除否决票!),这对我没有任何帮助,因为它仍然与JDT相关联,我一直在寻找根据问题“获取通用文件的属性”,请仔细阅读它-无论如何,谢谢你。如果你在包资源管理器中选择某个内容,它是一个ICompilationUnit。你无法回避这个问题。如果你想从中获取IFile,你可以调用unit.getResource(),但为什么在不必要时转换它。我将为您提供所处环境的正确答案。如果您在其他类型的查看器(非软件包资源管理器)中进行选择,您可以选择其他内容。有关导航结构,请参阅上面的JDT core指南。这取决于您选择内容的上下文。如果您在Package Explorer中选择项目,则必须处理Java模型,这是无法避免的。如果您在不同的视图中选择内容,则取决于该视图公开的内容。”理想情况下,我希望能够获得底层文件名、类型和内容
    Object firstElement = treeSelection.getFirstElement();
    
    IResource resource = (IResource)Platform.getAdapterManager().getAdapter(firstElement, IResource.class);