Give Each Editor Its Own Perspective
<p>I have a couple of editors with some detail views each that aren't relevant for the other editors. In fact, the customer doesn't want them there because they confuse them.</p>

<p>So I want to toggle the visibility of the views and thought the build-in perspectives in Eclipse might do the trick. I created a <code>IPartListener</code> like this:</p>

<pre><code>public class ToEachTheirOwnPartListener implements IPartListener {

    private final Map&lt;IWorkbenchPart, String&gt; partToPerspectiveId = new IdentityHashMap&lt;&gt;(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);
        }
    }
}
</code></pre>

<p>I'm struggeling with the <code>cloneEditorPerspective()</code> method because allmost all methods are not implemented in E4 or plain buggy.</p>

<p>What I want to do is to just clone an existing perspective like this (okay honestly I would  rather use <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=382209" rel="nofollow noreferrer">IPerspectiveRegistry#clonePerspective</a> but... E4):</p>

<pre><code>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);
</code></pre>

<p>But that throws the following exception (evidently the field <code>PerspectiveDescriptor.configElement</code> is null for the cloned perspective):</p>

<blockquote>
  <p>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)</p>
</blockquote>

<p>I could add <code>page.savePerspectiveAs(clone)</code> to remove the exception, but then for reasons that are completely beyond me not the default perspective is cloned but the currently active one.</p>

<p>So another try; we set the application to an empty perspective, then clone this one:</p>

<pre><code>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);
</code></pre>

<p>That code works, but <a href="https://stackoverflow.com/questions/41357225/iworkbenchpagesetperspective-duplicates-views">clones all views</a>.</p>

<p>If I close the views manually all hell breaks lose with something like that:</p>

<blockquote>
  <p>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$1(HandledContributionItem.java:802)
    at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem$3.run(HandledContributionItem.java:167)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)</p>
</blockquote>

<p>All variations I have tried seem to come down to these three: NPE, cloning the wrong perspective or duplicating the views.</p>

<p>Is there a way to give every editor its own perspective? If so, how?</p>