0

JDT 和其他 Eclipse 插件用问题状态(编译错误等)装饰编辑器标题图像。在我的插件中,我想模仿这种行为。

但是,看消息来源,JDT 似乎做了很多额外的处理来做装饰。

装饰器,尤其是轻量级的同上,是一种在图标上进行装饰的便捷方式,但我找不到以编程方式为编辑器的标题图像启用它们的方法。(而且我不想在我的插件中引入所有 JDT UI ......)

有没有这样的方法或者我需要实现我自己的 ILabelProvider 然后

public void updatedTitleImage(Image image) {
    setTitleImage(image);
}

像 JavaEditor 一样吗?

4

2 回答 2

1

似乎没有办法将装饰器与编辑器标题图像一起使用(至少从 3.7 开始)。

我最终创建了一个 EditorLabelUpdator,它实现了 IResourceChangeListener 接口(以找出标记何时更改),基本上是resourceChanged()方法。然后它使用一个简单的装饰器类型类,该类由 OverlayImageIcon 模式构建(您可以在 Google 上找到很多示例)。

从编辑器的初始化中调用构造函数,将编辑器作为参数发送,该参数被保存以获取资源及其标题图标。

编辑器还必须使用触发标题图标更新的回调方法进行修改(updatedTitleImage(Image image))。

这是我得到的代码的核心:

public void resourceChanged(IResourceChangeEvent event) {
    if (isMarkerChangeForResource(event, editor)) {
        /* Changes in markers on this resource, so re-decorate title image */
        decorate();
    }
}

private boolean isMarkerChangeForResource(IResourceChangeEvent event, AlanEditor editor) {
    boolean isMarkerChangeForThisResource;
    final IResource resource = ResourceUtil.getResource(editor.getEditorInput());
    final IPath path = resource.getFullPath();
    IResourceDelta delta = event.getDelta().findMember(path);
    isMarkerChangeForThisResource = (delta != null) && ((delta.getFlags() & IResourceDelta.MARKERS) != 0);
    return isMarkerChangeForThisResource;
}

public void decorate() {
    Shell shell = editor.getEditorSite().getShell();
    if (shell != null && !shell.isDisposed()) {
        shell.getDisplay().syncExec(new Runnable() {
            public void run() {
                Image decoratedImage = decorateImage(editor.getTitleImage(), getSeverity());
                editor.updatedTitleImage(decoratedImage);
            }
        });
    }
}

private Image decorateImage(Image titleImage, int severity) {
    final ImageRegistry registry = AlanIDEPlugin.getDefault().getImageRegistry();
    String key = createKey(severity);
    ImageDescriptor descriptor = AlanIDEPlugin.getImageDescriptor(key);
    if (descriptor != null)
        return descriptor.createImage();

    OverlayImageDescriptor overlayImageDescriptor = buildDecoratedImage(severity, key);
    registry.put(key, overlayImageDescriptor);
    return overlayImageDescriptor.createImage();
}

private String createKey(int severity) {
    String key;
    switch (severity) {
    case IMarker.SEVERITY_ERROR: key = EDITOR_TITLE_ICON + ".error"; break;
    case IMarker.SEVERITY_WARNING: key = EDITOR_TITLE_ICON + ".warning"; break;
    default: key = EDITOR_TITLE_ICON; break;
    }
    return key;
}

private OverlayImageDescriptor buildDecoratedImage(int severity, String key) {
    ImageDescriptor overlay = null;
    if (severity >= IMarker.SEVERITY_ERROR)
        overlay = AlanIDEPlugin.getImageDescriptor("ovr16.error_ovr");
    else if (severity == IMarker.SEVERITY_WARNING)
        overlay = AlanIDEPlugin.getImageDescriptor("ovr16.warning_ovr");
    ImageDescriptor baseImage = AlanIDEPlugin.getImageDescriptor(EDITOR_TITLE_ICON);
    OverlayImageDescriptor overlayIcon = new OverlayImageDescriptor(baseImage);

    if (overlay != null)
        overlayIcon.addOverlay(overlay, IDecoration.BOTTOM_LEFT);
    return overlayIcon;
}

private int getSeverity() {
    int severity = 0;
    try {
        final IResource resource = ResourceUtil.getResource(editor.getEditorInput());
        severity = resource.findMaxProblemSeverity(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
    } catch (CoreException e) {
        // Might be a project that is not open
    }
    return severity;
}

这是我能想到的最简单的解决方案。

于 2012-07-30T09:21:53.777 回答
0

是的,您可以使用一个扩展点来实现这一点。请看下面的代码:

 <!--define the decorator -->
<extension point="org.eclipse.ui.decorators">
    <decorator
    adaptable="true"
    class="org.example.PackageExplorerDecorator"
    id="org.example.PackageExplorerDecorator"
    label="File Decorator"
    lightweight="true"
    state="true">
 <enablement>
    <or>
       <objectClass
             name="org.eclipse.jdt.core.IMethod">
       </objectClass>
       <objectClass
             name="org.eclipse.core.resources.IResource">
       </objectClass>
    </or>
 </enablement>

对于 PackageExplorerDecorator:extends LabelProvider implements ILightweightLabelDecorator

于 2012-07-20T14:42:23.817 回答