如何为Eclipse e4 RCP应用程序重置视角?

3
在 application.e4xmi 文件中建立透视图后,我无法通过调用 IWorkbenchPage.resetPerspective() 来重置透视图。

你应该将问题部分写成一个问题,并将答案放在回答部分。然后在24小时后,你可以自己接受它(这完全没问题!)。 - oers
谢谢你的建议。 - n8n8baby
2个回答

4
我认为这可能会为其他人节省一些时间,也为自己记录下来。
重置e4透视图的诀窍如下(假设有一个基本的application.e4xmi文件,其中包含PerspectiveStack元素):
  1. In your application.e4xmi file, locate your PerspectiveStack under your Application/TrimmedWindow node. Record/set its ID.
  2. In Eclipse 4 Model Editor, drag your Perspective(s) from underneath your PerspectiveStack to Application/Snippets. (This will cause your perspective IDs to register with IPerspectiveRegistry, and provide a pristine state).
  3. Create new CopyPerspectiveSnippetProcessor. This will copy the perspectives in your snippets to your PerspectiveStack on startup. This makes it so you don't have to maintain two copies of each perspective element in your e4xmi file.

    package com.example.application.processors;
    
    import org.eclipse.e4.core.di.annotations.Execute;
    import org.eclipse.e4.ui.model.application.MApplication;
    import org.eclipse.e4.ui.model.application.ui.MUIElement;
    import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
    import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
    import org.eclipse.e4.ui.workbench.modeling.EModelService;
    
    /**
     * Copies all snippet perspectives to perspective stack called "MainPerspectiveStack" In order to register/reset perspective and not have to sync two copies in
     * e4xmi.
     * 
     */
    public class CopyPerspectiveSnippetProcessor {
        private static final String MAIN_PERSPECTIVE_STACK_ID = "MainPerspectiveStack";
    
        @Execute
        public void execute(EModelService modelService, MApplication application) {
            MPerspectiveStack perspectiveStack = (MPerspectiveStack) modelService.find(MAIN_PERSPECTIVE_STACK_ID, application);
    
            // Only do this when no other children, or the restored workspace state will be overwritten.
            if (!perspectiveStack.getChildren().isEmpty())
                return;
    
            // clone each snippet that is a perspective and add the cloned perspective into the main PerspectiveStack
            boolean isFirst = true;
            for (MUIElement snippet : application.getSnippets()) {
                if (snippet instanceof MPerspective) {
                    MPerspective perspectiveClone = (MPerspective) modelService.cloneSnippet(application, snippet.getElementId(), null);
                    perspectiveStack.getChildren().add(perspectiveClone);
                    if (isFirst) {
                        perspectiveStack.setSelectedElement(perspectiveClone);
                        isFirst = false;
                    }
                }
            }
        }
    }
    
  4. Register your CopyPerspectiveSnippetProcess into your plugin.xml file.

    <extension id="MainAppModel" point="org.eclipse.e4.workbench.model">
        <processor beforefragment="false" class="com.example.application.processors.CopyPerspectiveSnippetProcessor"/>
    </extension>
    
  5. Reset the perspective as normal. You will also want to set the perspective stack and the current perspective to visible, as these can sometimes be set to invisible. A sample handler might look like:

    import org.eclipse.e4.core.di.annotations.Execute;
    import org.eclipse.e4.ui.model.application.MApplication;
    import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
    import org.eclipse.e4.ui.workbench.modeling.EModelService;
    import org.eclipse.ui.PlatformUI;
    
    public class ResetPerspectiveHandler {
        private static final String MAIN_PERSPECTIVE_STACK_ID = "MainPerspectiveStack";
    
        @Execute
        public void execute(EModelService modelService, MApplication application) {
             MPerspectiveStack perspectiveStack = (MPerspectiveStack) modelService.find(MAIN_PERSPECTIVE_STACK_ID, application);
             PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().resetPerspective();
             perspectiveStack.getSelectedElement().setVisible(true);
             perspectiveStack.setVisible(true);
        }
    }
    

我添加了一个测试来防止覆盖持久化工作区状态。 - n8n8baby
我发现使用这种方法可能会干扰诸如UI元素尺寸保持不变等事物,因此请注意,这可能会产生无法接受的副作用。最终我们成功地限制了UI,使其删除了我们对透视重置的要求。 - n8n8baby
1
使用 PlatformUI 不是一个纯 e4 应用程序的正确解决方案。 - alphakermit
能否解释一下为什么不适用于有类似问题的任何人?我现在并不真正从事Java开发,所以我没有太多的上下文信息,但我知道当我处理这个问题时,E4还是相当新的。 - n8n8baby
2
使用 PlatformUI 强制你实现许多“旧”的 3.x 工作台捆绑依赖项,而通常会尝试避免设置纯 e4 应用程序。请参见 V Kash Singh 的答案以获取正确的“e4方式”(他代码中的第二种方法)。 - alphakermit

1
Reset perspective(当你启动e4应用程序而不清除工作空间,或者将其他视角切换到你的视角时)。
步骤1:在应用程序级别的模型片段中添加一个插件。 enter image description here 步骤2:创建Add-on类并实现EventHandler。
步骤3:在类中添加以下代码。
public class ResetPrespectiveAddOn implements EventHandler {

private static final String MY_PERSPECTIVE_ID = "myPrespectiveId";

@Inject
private IEventBroker broker;

@PostConstruct
public void loadPrespective() {

    broker.subscribe(UIEvents.ElementContainer.TOPIC_SELECTEDELEMENT, this);
}

@SuppressWarnings("restriction")
@Override
public void handleEvent(Event event) {

    //UIEvents.EventTags.ELEMENT is trigger  for all UI activity
    Object property = event.getProperty(UIEvents.EventTags.ELEMENT);
    if (!(property instanceof PerspectiveStackImpl)) {
        return;

    }

    // Reset perspective logic .
    IEclipseContext serviceContext = E4Workbench.getServiceContext();
    final IEclipseContext appContext = (IEclipseContext) serviceContext.getActiveChild();
    EModelService modelService = appContext.get(EModelService.class);
    MApplication application = serviceContext.get(MApplication.class);
    MWindow mWindow = application.getChildren().get(0);

    PerspectiveStackImpl perspectiveStack = (PerspectiveStackImpl) property;
    List<MPerspective> children = perspectiveStack.getChildren();
    for (MPerspective myPerspective : children) {
        if (myPerspective.getElementId().equals(MY_PERSPECTIVE_ID)) {

            //find active perspective
            MPerspective activePerspective = modelService.getActivePerspective(mWindow);
            if(activePerspective.getElementId().equals(MY_PERSPECTIVE_ID))

            //Reseting perspective  e3 way 
            PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().resetPerspective();


            // till now there is no direct e4 way to reset perspective 
            // but u can Add and remove e4 perspective with this code code              
            EPartService partService = serviceContext.get(EPartService.class);
            MPerspectiveStack perspectiveStack = (MPerspectiveStack) (MElementContainer<?>) activePerspective.getParent();
            int indexOf = perspectiveStack.getChildren().indexOf(activePerspective);
            perspectiveStack.getChildren().remove(indexOf);

            perspectiveStack.getChildren().add(myPerspective);
            partService.switchPerspective(myPerspective);
        }   
    }
}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接