给每个编辑自己的观点

Give Each Editor Its Own Perspective

我有几个编辑器,每个编辑器都有一些与其他编辑器无关的详细视图。事实上,客户不希望他们在那里,因为他们混淆了他们。

所以我想切换视图的可见性,并认为 Eclipse 中的内置透视图可以解决问题。我创建了一个 IPartListener 这样的:

public class ToEachTheirOwnPartListener implements IPartListener {

    private final Map<IWorkbenchPart, String> partToPerspectiveId = new IdentityHashMap<>(5);

    @Override
    public void partOpened(IWorkbenchPart part) {
        if (hasOwnPerspective(part)) {
            String perspectiveId = cloneEditorPerspective(part);
            this.partToPerspectiveId.put(part, perspectiveId);
        }
    }

    private static boolean hasOwnPerspective(IWorkbenchPart part) {
        return part instanceof IEditorPart;
    }

    String cloneEditorPerspective(IWorkbenchPart part) {
        final IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry();
        IWorkbenchPage page = part.getSite().getPage();
        // more later
    }

    @Override
    public void partBroughtToTop(IWorkbenchPart part) {
        if (hasOwnPerspective(part)) {
            final IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry();
            part.getSite().getPage().setPerspective(registry.findPerspectiveWithId(this.partToPerspectiveId.get(part)));
        }
    }

    @Override
    public void partClosed(IWorkbenchPart part) {
        if (hasOwnPerspective(part)) {
            final IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry();
            registry.deletePerspective(registry.findPerspectiveWithId(this.partToPerspectiveId.get(part)));
            this.partToPerspectiveId.remove(part);
        }
    }
}

我正在努力使用 cloneEditorPerspective() 方法,因为几乎所有方法都没有在 E4 或普通越野车中实现。

我想做的就是像这样克隆一个现有的透视图(好吧,老实说,我宁愿使用 IPerspectiveRegistry#clonePerspective 但是... E4):

page.savePerspectiveAs(page.getPerspective());

String defaultPerspectiveId = PlatformUI.getWorkbench().getPerspectiveRegistry().getDefaultPerspective();
final IPerspectiveDescriptor defaultPerspective = registry.findPerspectiveWithId(defaultPerspectiveId);
IPerspectiveDescriptor clone = ((PerspectiveRegistry) registry).createPerspective(UUID.randomUUID().toString(),
        (PerspectiveDescriptor) defaultPerspective);

但这会引发以下异常(显然字段 PerspectiveDescriptor.configElement 对于克隆的透视图为空):

java.lang.NullPointerException at org.eclipse.ui.internal.registry.PerspectiveDescriptor.createFactory(PerspectiveDescriptor.java:74) at org.eclipse.ui.internal.WorkbenchPage.setPerspective(WorkbenchPage.java:4053) at ToEachTheirOwnPartListener.partBroughtToTop(ToEachTheirOwnPartListener.java:65)

我可以添加 page.savePerspectiveAs(clone) 来删除异常,但由于完全超出我的原因,不是默认透视被克隆,而是当前活动的透视。

所以再试一次;我们将应用程序设置为一个空透视图,然后克隆这个:

IPerspectiveDescriptor perspective = registry.findPerspectiveWithId("org.acme.plugin.perspective");
window.getActivePage().setPerspective(perspective);
IPerspectiveDescriptor clone = ((PerspectiveRegistry) registry).createPerspective(UUID.randomUUID().toString(),
        (PerspectiveDescriptor) page.getPerspective());
page.savePerspectiveAs(clone);

该代码有效,但 clones all views

如果我手动关闭视图,所有地狱般的休息都会失去这样的东西:

java.lang.NullPointerException at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.canExecuteItem(HandledContributionItem.java:808) at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.access(HandledContributionItem.java:802) at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.run(HandledContributionItem.java:167) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)

我尝试过的所有变化似乎都归结为这三个:NPE、克隆错误的视角或复制视图。

有没有办法让每个编辑都有自己的观点?如果可以,怎么做?

显然,诀窍是只克隆当前活动的透视图。即切换到一个空的透视图,然后克隆:

    // we save the current perspective
    IPerspectiveDescriptor currentPerspective = page.getPerspective();
    if (currentPerspective != null) {
        // E4 sometimes lacks perspective
        page.savePerspectiveAs(currentPerspective);
    }

    // switch to the default one (should never have views)
    String defaultPerspectiveId = PlatformUI.getWorkbench().getPerspectiveRegistry().getDefaultPerspective();
    final IPerspectiveDescriptor defaultPerspective = registry.findPerspectiveWithId(defaultPerspectiveId);
    page.setPerspective(defaultPerspective);

    // clone it
    IPerspectiveDescriptor clone = ((PerspectiveRegistry) registry).createPerspective(String.valueOf(this.nextId++),
            (PerspectiveDescriptor) defaultPerspective);
    page.savePerspectiveAs(clone);

仍然有一堆随机的 NPE,因为视角是空的,但这就是 E4 的滚动方式。