I am writing an Eclipse plugin that will display a menu item in the context menu for a Java Project. I have written the plugin.xml as follows:
我正在编写一个Eclipse插件,它将在Java项目的上下文菜单中显示一个菜单项。我已经编写了插件。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>
So I am now trying to write the MenuContribution
class which extends CompoundContributionItem
so that I can create a dynamic menu and the contents of this menu are going to be based on a set of files that exist in the Java Project's root directory. But I am stuck trying to get the path to the root directory from within the getContributionItems
method.
因此,我现在正在尝试编写MenuContribution类,它扩展了CompoundContributionItem,这样我就可以创建一个动态菜单,该菜单的内容将基于Java项目根目录中存在的一组文件。但是我正试图从getContributionItems方法中获取到根目录的路径。
Based on the plugin.xml file I can be guarenteed that the method will only be called if a single Java Project is selected, so all I need to do is get the current selection and then get its absolute path. Any ideas? Or is there a better way to do this?
基于插件。我可以保证只有在一个Java项目被选中时才会调用这个方法,所以我需要做的就是获取当前的选择,然后获取它的绝对路径。什么好主意吗?或者有没有更好的方法?
3 个解决方案
#1
19
This should get you closer (if not solve it completely for you ;))
这应该会让你更接近(如果不是完全为你解决的话;))
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);
}
}
#2
6
Had a very long day working my way through the answers here and a whole lot of other answers and found the bit that finally got me there was to do a Java Reflection loop to study the Class and Interface structure of the selection from the Tree in the navigator. The Class introspection loop is in its final resting place but was originally much closer to the top of the execute method.
有一个非常漫长的一天工作过的答案和一大堆其他的答案,发现一点,终于我有做一个Java反射循环研究的类和接口结构选择树的导航器。类内省循环位于最后的位置,但最初更接近execute方法的顶部。
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;
}
}
#3
6
Since I wrote the previous answer I have written another couple of utility plugins and now have a generic starter for Eclipse Navigator Popups. The files are as follows:
自从我写了之前的答案,我已经写了另外两个实用插件,现在有了一个通用的Eclipse Navigator弹出窗口的入门。文件如下:
Basic manifest file
MANIFEST.MF
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
Basic properties file
build.properties
的build . properties
source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
META-INF/,\
.
Plugin file
In particular note how <command commandId=...> of the <menuContribution...> <menu..> in the <extension point="org.eclipse.ui.menus"> extension point links to the <handler commandId=...> in the <extension point="org.eclipse.ui.handlers"> extension point this permits us to link multiple menu contributions to a single handler.
特别注意
Also of note is the fact that there are multiple locationURI's as these can change from one perspective to another.
同样值得注意的是,有多个locationURI,因为它们可以从一个角度更改到另一个角度。
plugin.xml
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>
To find out more about the plugin for the current selection click on a file and use ALT-SHIFT-F1 for the Plug-in Selection Spy
要了解有关当前选择的插件的更多信息,请单击一个文件,并使用ALT-SHIFT-F1作为插件选择间谍
Use ALT-SHIFT-F2 for the Plug-in Menu Spy. Note press the ALT-SHIFT-F2 combination before right clicking and selecting the popup menu item of interest.
使用ALT-SHIFT-F2的插件菜单间谍。注意:在右键单击并选择感兴趣的弹出菜单项之前,按ALT-SHIFT-F2组合。
Finally the code for the plug-in.
最后是插件的代码。
NavigatorPopupHandler.java
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;
}
}
And the result of running the plug-in on its own java file.
以及在自己的java文件上运行插件的结果。
#1
19
This should get you closer (if not solve it completely for you ;))
这应该会让你更接近(如果不是完全为你解决的话;))
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);
}
}
#2
6
Had a very long day working my way through the answers here and a whole lot of other answers and found the bit that finally got me there was to do a Java Reflection loop to study the Class and Interface structure of the selection from the Tree in the navigator. The Class introspection loop is in its final resting place but was originally much closer to the top of the execute method.
有一个非常漫长的一天工作过的答案和一大堆其他的答案,发现一点,终于我有做一个Java反射循环研究的类和接口结构选择树的导航器。类内省循环位于最后的位置,但最初更接近execute方法的顶部。
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;
}
}
#3
6
Since I wrote the previous answer I have written another couple of utility plugins and now have a generic starter for Eclipse Navigator Popups. The files are as follows:
自从我写了之前的答案,我已经写了另外两个实用插件,现在有了一个通用的Eclipse Navigator弹出窗口的入门。文件如下:
Basic manifest file
MANIFEST.MF
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
Basic properties file
build.properties
的build . properties
source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
META-INF/,\
.
Plugin file
In particular note how <command commandId=...> of the <menuContribution...> <menu..> in the <extension point="org.eclipse.ui.menus"> extension point links to the <handler commandId=...> in the <extension point="org.eclipse.ui.handlers"> extension point this permits us to link multiple menu contributions to a single handler.
特别注意
Also of note is the fact that there are multiple locationURI's as these can change from one perspective to another.
同样值得注意的是,有多个locationURI,因为它们可以从一个角度更改到另一个角度。
plugin.xml
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>
To find out more about the plugin for the current selection click on a file and use ALT-SHIFT-F1 for the Plug-in Selection Spy
要了解有关当前选择的插件的更多信息,请单击一个文件,并使用ALT-SHIFT-F1作为插件选择间谍
Use ALT-SHIFT-F2 for the Plug-in Menu Spy. Note press the ALT-SHIFT-F2 combination before right clicking and selecting the popup menu item of interest.
使用ALT-SHIFT-F2的插件菜单间谍。注意:在右键单击并选择感兴趣的弹出菜单项之前,按ALT-SHIFT-F2组合。
Finally the code for the plug-in.
最后是插件的代码。
NavigatorPopupHandler.java
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;
}
}
And the result of running the plug-in on its own java file.
以及在自己的java文件上运行插件的结果。