【问题标题】:Eclipse Plugin: how to get the path to the currently selected projectEclipse Plugin:如何获取当前选中项目的路径
【发布时间】:2011-10-17 01:31:47
【问题描述】:

我正在编写一个 Eclipse 插件,它将在 Java 项目的上下文菜单中显示一个菜单项。我将plugin.xml写成如下:

<plugin>
   <extension
         point="org.eclipse.ui.menus">
      <menuContribution
            locationURI="popup:org.eclipse.jdt.ui.PackageExplorer">
         <dynamic
               class="uk.co.dajohnston.plugin.classpathswitcher.menu.MenuContribution"
               id="uk.co.dajohnston.plugin.classpathSwitcher.switchMenuContribution">
            <visibleWhen>
               <with
                     variable="activeMenuSelection">
                  <iterate>
                     <adapt
                           type="org.eclipse.jdt.core.IJavaProject">
                     </adapt>
                  </iterate>
                  <count
                        value="1">
                  </count>
               </with>
            </visibleWhen>
         </dynamic>
      </menuContribution>
   </extension>

</plugin>

所以我现在正在尝试编写扩展 CompoundContributionItemMenuContribution 类,以便我可以创建一个动态菜单,该菜单的内容将基于 Java 项目中存在的一组文件根目录。但我一直试图从getContributionItems 方法中获取根目录的路径。

基于 plugin.xml 文件,我可以保证只有在选择了单个 Java 项目时才会调用该方法,所以我需要做的就是获取当前选择,然后获取其绝对路径。有任何想法吗?或者有更好的方法吗?

【问题讨论】:

    标签: java eclipse eclipse-plugin eclipse-pde


    【解决方案1】:

    这应该让你更接近(如果不能为你完全解决它;))

        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (window != null)
        {
            IStructuredSelection selection = (IStructuredSelection) window.getSelectionService().getSelection();
            Object firstElement = selection.getFirstElement();
            if (firstElement instanceof IAdaptable)
            {
                IProject project = (IProject)((IAdaptable)firstElement).getAdapter(IProject.class);
                IPath path = project.getFullPath();
                System.out.println(path);
            }
        }
    

    【讨论】:

    • 谢谢,它把我带到了那里。 getFullPath() 似乎只是返回项目的名称,但 getLocation() 返回完整的绝对路径。
    • 我试过了,但 eclipse 无法解析 IProject,你知道为什么吗?谢谢
    • 已经有一段时间了...你检查过你得到的 IAdaptable 的类型了吗?另外,您的项目视图中有任何选择吗?
    【解决方案2】:

    自从我写了上一个答案后,我又写了几个实用插件,现在有了一个用于 Eclipse Navigator Popups 的通用启动器。文件如下:

    基本清单文件

    MANIFEST.MF

    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: NavigatorPopup
    Bundle-SymbolicName: com.nsd.NavigatorPopup;singleton:=true
    Bundle-Version: 1.0.0.1
    Bundle-Vendor: NSD
    Require-Bundle: org.eclipse.ui,
     org.eclipse.core.resources,
     org.eclipse.core.runtime
    Bundle-RequiredExecutionEnvironment: JavaSE-1.6
    

    基本属性文件

    build.properties

    source.. = src/
    output.. = bin/
    bin.includes = plugin.xml,\
                   META-INF/,\
                   .
    

    插件文件

    特别注意如何="org.eclipse.ui.menus"> 扩展点链接到 扩展点,这允许我们将多个菜单贡献链接到单个处理程序。

    另外值得注意的是,有多个 locationURI,因为它们可以从一个角度改变到另一个角度。

    plugin.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <?eclipse version="3.4"?>
    <plugin>
        <extension point="org.eclipse.ui.commands">
            <category name="NSD Category" id="com.nsd.NavigatorPopup.commands.category"/>
            <command name="Navigator Popup" categoryId="com.nsd.NavigatorPopup.commands.category" id="com.nsd.NavigatorPopup.commands.navigatorPopupCommand"/>
        </extension>
        <extension point="org.eclipse.ui.handlers">
            <handler commandId="com.nsd.NavigatorPopup.commands.navigatorPopupCommand" class="com.nsd.navigatorpopup.NavigatorPopupHandler"/>
        </extension>
        <extension point="org.eclipse.ui.menus">
            <menuContribution locationURI="popup:org.eclipse.jdt.ui.PackageExplorer?after=additions">
                <menu label="Popup Utilities">
                    <command commandId="com.nsd.NavigatorPopup.commands.navigatorPopupCommand" id="com.nsd.NavigatorPopup.menus.navigatorPopupCommand"/>
                </menu>
            </menuContribution>
            <menuContribution locationURI="popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu?after=additions">
                <menu label="Popup Utilities">
                    <command commandId="com.nsd.NavigatorPopup.commands.navigatorPopupCommand" id="com.nsd.NavigatorPopup.menus.navigatorPopupCommand"/>
                </menu>
            </menuContribution>
        </extension>
    </plugin>
    

    要了解有关当前选择的插件的更多信息,请单击文件并使用 ALT-SHIFT-F1 作为插件选择间谍

    对插件菜单间谍使用 ALT-SHIFT-F2。 注意在右键单击并选择感兴趣的弹出菜单项之前按 ALT-SHIFT-F2 组合。

    最后是插件的代码。

    NavigatorPopupHandler.java

    package com.nsd.navigatorpopup;
    
    import org.eclipse.core.commands.AbstractHandler;
    import org.eclipse.core.commands.ExecutionEvent;
    import org.eclipse.core.commands.ExecutionException;
    import org.eclipse.core.resources.IFile;
    import org.eclipse.core.resources.IProject;
    import org.eclipse.core.resources.IResource;
    import org.eclipse.core.runtime.IAdaptable;
    import org.eclipse.ui.IWorkbenchPage;
    import org.eclipse.ui.IWorkbenchWindow;
    import org.eclipse.ui.handlers.HandlerUtil;
    import org.eclipse.jface.dialogs.MessageDialog;
    import org.eclipse.jface.viewers.ISelection;
    import org.eclipse.jface.viewers.ITreeSelection;
    import org.eclipse.jface.viewers.TreePath;
    import org.eclipse.jface.viewers.TreeSelection;
    
    // ====================================================================================================================
    // This handler will obtain the core information about a file from a navigator popup menu
    // ====================================================================================================================
    public class NavigatorPopupHandler extends AbstractHandler {
        private IWorkbenchWindow window;
        private IWorkbenchPage activePage;
    
        private IProject theProject;
        private IResource theResource;
        private IFile theFile;
    
        private String workspaceName;
        private String projectName;
        private String fileName;
    
        public NavigatorPopupHandler() {
            // Empty constructor
        }
    
        public Object execute(ExecutionEvent event) throws ExecutionException {
            // Get the project and file name from the initiating event if at all possible
            if(!extractProjectAndFileFromInitiatingEvent(event)) {
                return null;
            }
    
            // CODE THAT USES THE FILE GOES HERE
            MessageDialog.openInformation(this.window.getShell(), "NavigatorPopup", String.format("File Details.\n\nWorkspace=%s\nProject=%s\nFile=%s", workspaceName, projectName, fileName));
    
            return null;
        }
    
        private boolean extractProjectAndFileFromInitiatingEvent(ExecutionEvent event) {
            // ============================================================================================================
            // The execute method of the handler is invoked to handle the event. As we only contribute to Explorer
            // Navigator views we expect to get a selection tree event
            // ============================================================================================================
            this.window = HandlerUtil.getActiveWorkbenchWindow(event);
            // Get the active WorkbenchPage
            this.activePage = this.window.getActivePage();
    
            // Get the Selection from the active WorkbenchPage page
            ISelection selection = this.activePage.getSelection();
            if(selection instanceof ITreeSelection) {
                TreeSelection treeSelection = (TreeSelection) selection;
                TreePath[] treePaths = treeSelection.getPaths();
                TreePath treePath = treePaths[0];
    
                // The TreePath contains a series of segments in our usage:
                // o The first segment is usually a project
                // o The last segment generally refers to the file
    
                // The first segment should be a IProject
                Object firstSegmentObj = treePath.getFirstSegment();
                this.theProject = (IProject) ((IAdaptable) firstSegmentObj).getAdapter(IProject.class);
                if(this.theProject == null) {
                    MessageDialog.openError(this.window.getShell(), "Navigator Popup", getClassHierarchyAsMsg(
                                    "Expected the first segment to be IAdapatable to an IProject.\nBut got the following class hierarchy instead.", "Make sure to directly select a file.",
                                    firstSegmentObj));
                    return false;
                }
    
                // The last segment should be an IResource
                Object lastSegmentObj = treePath.getLastSegment();
                this.theResource = (IResource) ((IAdaptable) lastSegmentObj).getAdapter(IResource.class);
                if(this.theResource == null) {
                    MessageDialog.openError(this.window.getShell(), "Navigator Popup", getClassHierarchyAsMsg(
                                    "Expected the last segment to be IAdapatable to an IResource.\nBut got the following class hierarchy instead.", "Make sure to directly select a file.",
                                    firstSegmentObj));
                    return false;
                }
    
                // As the last segment is an IResource we should be able to get an IFile reference from it
                this.theFile = (IFile) ((IAdaptable) lastSegmentObj).getAdapter(IFile.class);
    
                // Extract additional information from the IResource and IProject
                this.workspaceName = this.theResource.getWorkspace().getRoot().getLocation().toOSString();
                this.projectName = this.theProject.getName();
                this.fileName = this.theResource.getName();
    
                return true;
            } else {
                String selectionClass = selection.getClass().getSimpleName();
                MessageDialog.openError(this.window.getShell(), "Unexpected Selection Class", String.format("Expected a TreeSelection but got a %s instead.\nProcessing Terminated.", selectionClass));
            }
    
            return false;
        }
    
        @SuppressWarnings("rawtypes")
        private static String getClassHierarchyAsMsg(String msgHeader, String msgTrailer, Object theObj) {
            String msg = msgHeader + "\n\n";
    
            Class theClass = theObj.getClass();
            while(theClass != null) {
                msg = msg + String.format("Class=%s\n", theClass.getName());
                Class[] interfaces = theClass.getInterfaces();
                for(Class theInterface : interfaces) {
                    msg = msg + String.format("    Interface=%s\n", theInterface.getName());
                }
                theClass = theClass.getSuperclass();
            }
    
            msg = msg + "\n" + msgTrailer;
    
            return msg;
        }
    }
    

    以及在自己的java文件上运行插件的结果。

    【讨论】:

      【解决方案3】:

      花了很长的时间来解决这里的答案和很多其他的答案,并发现最终让我到达那里的一点是做一个 Java 反射循环来研究选择的类和接口结构导航器中的树。 Class introspection 循环处于其最后的休息位置,但最初更接近执行方法的顶部。

      import org.eclipse.core.commands.AbstractHandler;
      import org.eclipse.core.commands.ExecutionEvent;
      import org.eclipse.core.commands.ExecutionException;
      import org.eclipse.core.resources.IFile;
      import org.eclipse.core.runtime.IAdaptable;
      import org.eclipse.ui.IWorkbenchPage;
      import org.eclipse.ui.IWorkbenchWindow;
      import org.eclipse.ui.handlers.HandlerUtil;
      import org.eclipse.jface.viewers.ISelection;
      import org.eclipse.jface.viewers.IStructuredSelection;
      import org.eclipse.jface.viewers.ITreeSelection;
      import org.eclipse.jface.viewers.TreePath;
      import org.eclipse.jface.viewers.TreeSelection;
      
      public class MyHandler extends AbstractHandler {
      /**
       * The constructor.
       */
      public MyHandler() {
      }
      
      public Object execute(ExecutionEvent event) throws ExecutionException {
          IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
          IWorkbenchPage activePage = window.getActivePage();
          ISelection selection = activePage.getSelection();
          if (selection != null) {
              System.out.println("Got selection");
              if (selection instanceof IStructuredSelection) {
                  System.out.println("Got a structured selection");
                  if (selection instanceof ITreeSelection) {
                      TreeSelection treeSelection = (TreeSelection) selection;
                      TreePath[] treePaths = treeSelection.getPaths();
                      TreePath treePath = treePaths[0];
      
                      System.out.println("Last");
                      Object lastSegmentObj = treePath.getLastSegment();
                      Class currClass = lastSegmentObj.getClass();
                      while(currClass != null) {
                          System.out.println("  Class=" + currClass.getName());
                          Class[] interfaces = currClass.getInterfaces();
                          for(Class interfacey : interfaces) {
                              System.out.println("   I=" + interfacey.getName());
                          }
                          currClass = currClass.getSuperclass();
                      }
                      if(lastSegmentObj instanceof IAdaptable) {
                          IFile file = (IFile) ((IAdaptable) lastSegmentObj).getAdapter(IFile.class);
                          if(file != null) {
                              System.out.println("File=" + file.getName());
                              String path = file.getRawLocation().toOSString();
                              System.out.println("path: " + path);
                          }
                      }
                  }
              }
          }
          return null;
      }
      }
      

      【讨论】:

        猜你喜欢
        • 2010-09-07
        • 1970-01-01
        • 1970-01-01
        • 2013-06-15
        • 1970-01-01
        • 1970-01-01
        • 2019-02-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多