我正在编写一个Eclipse插件。它运行Java代码的代码分析,并使用ListViewer报告违反某些条件的代码行。当有人在列表查看器中选择其中一行时,我想打开该文件的Eclipse Java文件编辑器并转到该行。分析的工作方式是,每个违规都有一个字段,用于保存违规发生的文件作为标准java.io.File。因此,我需要将其转换为IFile,以便我可以在Eclipse Java编辑器中打开它。
这是用户单击listviewer中的一行时运行的大部分代码。违反是我用来表示违反某些标准的特定Java代码行的类:
Violation selectedViolation = <I get this from the ListViewer>
IPath path = new Path(violation.getSourceFile().getAbsolutePath());
IFile toOpen = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
if (editorPart == null) {
IWorkbenchPage curPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
editorPart = IDE.openEditor(curPage, toOpen, true);
}
运行这个,我在调用IDE.openEditor(对应于CalisthenicsView.java:75)的行上得到IllegalArgumentException:
at org.eclipse.ui.part.FileEditorInput.getPath(FileEditorInput.java:218)
at org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(WorkbenchPage.java:3163)
at org.eclipse.ui.internal.WorkbenchPage.access$25(WorkbenchPage.java:3149)
at org.eclipse.ui.internal.WorkbenchPage$10.run(WorkbenchPage.java:3131)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:3126)
at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:3090)
at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:3080)
at org.eclipse.ui.ide.IDE.openEditor(IDE.java:541)
at org.eclipse.ui.ide.IDE.openEditor(IDE.java:500)
at com.chairbender.eclipse.object_calisthenics_analyzer.views.CalisthenicsView$1.selectionChanged(CalisthenicsView.java:75)
我已经查看了在FileEditorInput.java:218中抛出此内容的源代码行。显然它会这样做(其中&#34;文件&#34;与#34; toOpen&#34;在第一个代码块中相同):
final URI locationURI = file.getLocationURI();
if (locationURI == null)
throw new IllegalArgumentException();
对我来说,似乎.getFile(path)返回一个没有locationURI的IFile,出于某种原因。我不知道为什么。
有没有办法解决这个问题?有没有不同的方法可以实现这一点(将Java编辑器打开到特定文件的特定行)?请记住,我无法访问IProject,因为此分析可以在工作区中的任何项目上运行,甚至可以在整个工作区中运行。
编辑:我不能理解的另一件事是尝试调用FileEditorInput.getPaht()的代码。在3163行看看WorkbenchPage.busyOpenEditor:// Special handling for external editors (they have no tabs...)
if ("org.eclipse.ui.systemExternalEditor".equals(editorId)) { //$NON-NLS-1$
IPathEditorInput fileInput = getPathEditorInput(input);
if (fileInput == null) {
throw new PartInitException(WorkbenchMessages.EditorManager_systemEditorError);
}
String fullPath = fileInput.getPath().toOSString();
Program.launch(fullPath);
return null;
}
这是调用FileEditorInput.getPath()的代码。显然它正试图打开一个名为“外部编辑器”的东西,这听起来并不像我想要它做的那样。我只想打开默认的Java源代码编辑器。这听起来像是在试图打开别的东西。
另外,我想补充一点,toOpen(我试图打开的IFile)的.toString()值是: L /编程/运行时间New_configuration / slackbot电阻/ SRC /主/ JAVA / COM / chairbender / slackbot /电阻/ ResistanceBot.java
...所以它绝对不是null或无效我会认为Eclipse知道它是一个Java文件。
答案 0 :(得分:2)
IPath path = new Path(violation.getSourceFile().getAbsolutePath());
IFile toOpen = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
您似乎正在将绝对文件路径传递给getFile
方法。这方面的JavaDoc说:
这是一个资源句柄操作;无论是资源还是资源 结果需要存在于工作空间中。验证检查 资源句柄时不执行资源名称/路径 建造;相反,它是在资源自动完成的 创建
提供的路径可以是绝对路径或相对路径;无论哪种情况,都是 解释为相对于此资源并附加到此 容器的完整路径,以形成结果资源的完整路径。 尾随分隔符将被忽略。生成的资源的路径 必须至少有两个部分。
因此路径被解释为相对于当前工作空间(即您的测试工作空间而不是您的开发工作空间)。没有进行测试以查看文件是否确实存在。
IDE.openEditor
内的异常是因为IFile
似乎不在工作区中的有效项目中。这也是它试图打开外部编辑器的原因。
如果您要打开不在工作区中的文件,则需要使用IURIEditorInput
实施的FileStoreEditorInput
:
IFileStore store = EFS.getStore(file.toURI());
IEditorInput input = new FileStoreEditorInput(store);
IDE.openEditor(page, input, "editor id", true);
注意:某些编辑器不支持不在工作区中的文件,其他编辑器可能会减少功能。
Java编辑器的编辑器ID由JavaUI.ID_CU_EDITOR
(“org.eclipse.jdt.ui.CompilationUnitEditor”)提供
如果您的文件位于工作区中,但只有文件的绝对路径使用IWorkspaceRoot.getFileForLocation
:
IFile toOpen = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
注意:如果找不到null
,则会返回IFile
。
答案 1 :(得分:0)
这个问题是由于我不理解ResourcesPlugin.getWorkspace()。getRoot()。getFile(path)的文档。它说“提供的路径可能是绝对的或相对的;在任何一种情况下,它都被解释为相对于这个资源并被附加”,这让我很困惑。如何将绝对路径解释为相对于任何东西?如果我将它传递给绝对路径,为什么不通过检查工作空间路径是否在传递的绝对路径的开头处而使该路径相对于工作空间?我希望该方法能够更智能地运行。
以下对我有用。我必须使用IPath.makeRelativeTo方法通过砍掉与工作空间相对应的路径部分,将绝对路径从java.io.File转换为相对路径:
IPath path = new Path(violation.getSourceFile().getAbsolutePath());
IPath workspacePath = ResourcesPlugin.getWorkspace().getRoot().getLocation();
path = path.makeRelativeTo(workspacePath);
IFile toOpen = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
使用getFileForLocation而不是getFile的建议不起作用。无论路径是相对路径还是绝对路径,该方法总是为我返回null。我认为它已经坏了。