如何创建Eclipse插件中的问题标记?求完整示例项目
完整可运行的Eclipse Java编辑器问题标记示例项目
这个示例实现一个简单的Eclipse插件:检测Java文件中的System.out.println语句,在对应行生成警告标记,并在问题视图中显示。
项目结构
com.example.javamarker/ ├── plugin.xml └── src/ └── com/ └── example/ └── javamarker/ ├── Activator.java ├── JavaMarkerGenerator.java └── MarkerBuilder.java
核心代码
1. plugin.xml(插件配置)
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.4"?> <plugin> <extension point="org.eclipse.core.resources.builders"> <builder hasNature="true" id="com.example.javamarker.builder" name="Java Marker Builder"> <run class="com.example.javamarker.JavaMarkerGenerator"> </run> </builder> </extension> <extension point="org.eclipse.core.resources.natures"> <nature id="com.example.javamarker.nature" name="Java Marker Nature" class="com.example.javamarker.Activator$MarkerNature"> </nature> </extension> <extension point="org.eclipse.core.resources.markers"> <markerType id="com.example.javamarker.customMarker" name="Custom Java Marker" super="org.eclipse.core.resources.problemmarker"> <persistent value="true"> </persistent> </markerType> </extension> </plugin>
2. Activator.java(插件激活类)
package com.example.javamarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectNature; import org.eclipse.core.runtime.CoreException; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; public class Activator extends AbstractUIPlugin { public static final String PLUGIN_ID = "com.example.javamarker"; private static Activator plugin; @Override public void start(BundleContext context) throws Exception { super.start(context); plugin = this; } @Override public void stop(BundleContext context) throws Exception { plugin = null; super.stop(context); } public static Activator getDefault() { return plugin; } public static class MarkerNature implements IProjectNature { public static final String NATURE_ID = PLUGIN_ID + ".nature"; private IProject project; @Override public void configure() throws CoreException { IProjectDescription desc = project.getDescription(); String[] builders = desc.getBuildSpec(); for (String builder : builders) { if (JavaMarkerGenerator.BUILDER_ID.equals(builder)) { return; } } String[] newBuilders = new String[builders.length + 1]; System.arraycopy(builders, 0, newBuilders, 0, builders.length); newBuilders[builders.length] = JavaMarkerGenerator.BUILDER_ID; desc.setBuildSpec(newBuilders); project.setDescription(desc, null); } @Override public void deconfigure() throws CoreException { IProjectDescription desc = project.getDescription(); String[] builders = desc.getBuildSpec(); for (int i = 0; i < builders.length; i++) { if (JavaMarkerGenerator.BUILDER_ID.equals(builders[i])) { String[] newBuilders = new String[builders.length - 1]; System.arraycopy(builders, 0, newBuilders, 0, i); System.arraycopy(builders, i + 1, newBuilders, i, builders.length - i - 1); desc.setBuildSpec(newBuilders); project.setDescription(desc, null); return; } } } @Override public IProject getProject() { return project; } @Override public void setProject(IProject project) { this.project = project; } } }
3. JavaMarkerGenerator.java(标记生成逻辑)
package com.example.javamarker; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; public class JavaMarkerGenerator extends IncrementalProjectBuilder { public static final String BUILDER_ID = Activator.PLUGIN_ID + ".builder"; private static final String MARKER_TYPE = Activator.PLUGIN_ID + ".customMarker"; @Override protected IProject[] build(int kind, @SuppressWarnings("rawtypes") Map args, IProgressMonitor monitor) throws CoreException { if (kind == FULL_BUILD) { fullBuild(getProject(), monitor); } else { IResourceDelta delta = getDelta(getProject()); if (delta == null) { fullBuild(getProject(), monitor); } else { incrementalBuild(delta, monitor); } } return null; } private void fullBuild(IProject project, IProgressMonitor monitor) throws CoreException { project.deleteMarkers(MARKER_TYPE, true, IResource.DEPTH_INFINITE); visitResources(project, monitor); } private void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException { delta.accept(deltaResource -> { IResource resource = deltaResource.getResource(); if (resource.getType() == IResource.FILE && resource.getName().endsWith(".java")) { try { resource.deleteMarkers(MARKER_TYPE, false, IResource.DEPTH_ZERO); generateMarkers((IFile) resource); } catch (CoreException | IOException e) { e.printStackTrace(); } } return true; }); } private void visitResources(IResource resource, IProgressMonitor monitor) throws CoreException { if (resource.getType() == IResource.FILE && resource.getName().endsWith(".java")) { try { generateMarkers((IFile) resource); } catch (IOException e) { e.printStackTrace(); } } else if (resource.getType() == IResource.FOLDER || resource.getType() == IResource.PROJECT) { for (IResource child : resource.members()) { visitResources(child, monitor); } } } private void generateMarkers(IFile file) throws IOException, CoreException { try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents()))) { String line; int lineNum = 0; while ((line = reader.readLine()) != null) { lineNum++; if (line.contains("System.out.println")) { MarkerBuilder.createMarker(file, lineNum, "避免使用System.out.println进行调试", MARKER_TYPE, IResource.DEPTH_ZERO); } } } } }
4. MarkerBuilder.java(标记构建工具类)
package com.example.javamarker; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; public class MarkerBuilder { public static void createMarker(IResource resource, int lineNumber, String message, String markerType, int depth) throws CoreException { IMarker marker = resource.createMarker(markerType); marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); marker.setAttribute(IMarker.MESSAGE, message); marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING); marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_NORMAL); } }
部署与测试
- 确保你的Eclipse安装了Plugin Development Environment(PDE),未安装可通过Help → Eclipse Marketplace搜索安装。
- 右键项目 → Run As → Eclipse Application,启动新的Eclipse实例。
- 在新实例中创建Java项目,右键项目 → Configure → Add Nature,选择"Java Marker Nature"。
- 创建Java类,写入
System.out.println("test");代码。 - 保存文件后,编辑器右侧标记栏会出现黄色警告图标,打开Window → Show View → Problems可查看生成的警告标记。
自定义扩展说明
- 修改
JavaMarkerGenerator.generateMarkers方法中的检测逻辑,即可实现自定义编码规则的检测。 - 若需替换标记图标,可在项目中添加
icons目录放入图标文件,再在plugin.xml中添加org.eclipse.ui.ide.markerImageProviders扩展配置。
内容的提问来源于stack exchange,提问作者zenith
相关产品推荐
相关产品推荐

