Java 如何在EclipseRCPE4中创建多个窗口

Java 如何在EclipseRCPE4中创建多个窗口,java,eclipse,eclipse-rcp,e4,Java,Eclipse,Eclipse Rcp,E4,我们希望实现一个可能有多个窗口的RCP应用程序(mWindows) 对于不同的数据。Windows必须是独立的(与Eclipse IDE不同) 窗口菜单项),但必须能够从中复制和粘贴、拖放内容 从一扇窗户到另一扇窗户。想象一下像Word这样的应用程序,您可以 打开多个文档。我们尝试了各种方法,但都很安静 很难找到正确的e4方式: 1.为每个窗口创建新的应用程序 我们的第一种方法是为每个应用程序创建并运行一个完整的新应用程序 新窗口。但这听起来不是e4的正确方式。它也是童车:钥匙 绑定无法正常工作

我们希望实现一个可能有多个窗口的RCP应用程序(
mWindows
) 对于不同的数据。Windows必须是独立的(与Eclipse IDE不同) 窗口菜单项),但必须能够从中复制和粘贴、拖放内容 从一扇窗户到另一扇窗户。想象一下像Word这样的应用程序,您可以 打开多个文档。我们尝试了各种方法,但都很安静 很难找到正确的e4方式:

1.为每个窗口创建新的应用程序 我们的第一种方法是为每个应用程序创建并运行一个完整的新应用程序 新窗口。但这听起来不是e4的正确方式。它也是童车:钥匙 绑定无法正常工作,并且会为每个新绑定调用
LifecycleManager
每个新窗口的应用程序及其相关信息,这些信息不应被删除

E4Application application = new E4Application();
BundleContext context = InternalPlatform.getDefault().getBundleContext();
ServiceReference<?> appContextService = context.getServiceReference(IApplicationContext.class);
IApplicationContext iac = (IApplicationContext) context.getService(appContextService);
IWorkbench workbench = application.createE4Workbench(iac, display);
 final E4Workbench implementation = (E4Workbench) workbench;
implementation.createAndRunUI(workbench.getApplication());
看起来EclipseIDE使用了RCP3兼容层。我们没有 找到了获取
IWorkbench
对象的方法。都不是
PlatformUI#getWorkbench()
,也不通过应用程序上下文或捆绑包 上下文

3.克隆主窗口 我们偶然发现 n-mtrimmedwindow-complete-with-perspectives-etc并进行了大量的试验和测试 错误,并产生了以下代码:

class ElementCloningBasedCreator {

    EModelService models = ...; // injected
    MApplication app = ...; // injected

    public void openNewWindow() {
        MWindow originWindow = (MWindow) models.find("the.main.window.id", app);
        MWindow newWindow = (MWindow) models.cloneElement(originWindow, null);

        MPerspectiveStack newPerspectiveStack =
            (MPerspectiveStack) models.find(the.main.perspective.stack.id, newWindow);
        newPerspectiveStack.setParent((MElementContainer) newWindow);

        addTo(app, newWindow);

        // Clone the shared elements. If we don't do that the rendering somewhere 
        // deep in the rabbit hole throws assertion erros because the recurisve 
        // finding of an element fails because the search root is null.
        for (final MUIElement originSharedElement : originWindow.getSharedElements()) {
            final MUIElement clonedSharedElement = models.cloneElement(originSharedElement, null);
            clonedSharedElement.setParent((MElementContainer) newWindow);
            newWindow.getSharedElements().add(clonedSharedElement);
        }

        cloneSnippets(app, originWindow, newPerspectiveStack, newWindow);
        newWindow.setContext(createContextForNewWindow(originWindow, newWindow));
        newWindow.setToBeRendered(true);
        newWindow.setVisible(true);
        newWindow.setOnTop(true);
        models.bringToTop(newWindow);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void addTo(MElementContainer target, MUIElement child) {
        child.setParent(target);
        target.getChildren().add(child);
    }

    /**
     * Clone each snippet that is a perspective and add the cloned perspective 
     * into the main PerspectiveStack.
     */
    private void cloneSnippets(MApplication app, MWindow originWindow,
        MPerspectiveStack newPerspectiveStack, MWindow newWindow) {
        boolean isFirstSnippet = true;

        for (MUIElement snippet : app.getSnippets()) {
            if (ignoreSnippet(snippet)) {
                continue;
            }

            String snipetId = snippet.getElementId();
            MPerspective clonedPerspective = 
                (MPerspective) models.cloneSnippet(app, snipetId, originWindow);
            findPlaceholdersAndCloneReferencedParts(clonedPerspective, newWindow);
            addTo(newPerspectiveStack, clonedPerspective);

            if (isFirstSnippet) {
                newPerspectiveStack.setSelectedElement(clonedPerspective);
                isFirstSnippet = false;
            }
        }
    }

    private boolean ignoreSnippet(MUIElement snippet) {
        return !(snippet instanceof MPerspective);
    }

    private void findPlaceholdersAndCloneReferencedParts(MPerspective clonedPerspective, MWindow newWindow) {
        List<MPlaceholder> placeholders = 
            models.findElements(clonedPerspective, null, MPlaceholder.class, null);

        for (MPlaceholder placeholder : placeholders) {
            MUIElement reference = placeholder.getRef();

            if (reference != null) {
                placeholder.setRef(models.cloneElement(placeholder.getRef(), null));
                placeholder.getRef().setParent((MElementContainer) newWindow);
            }
        }
    }
}
类元素CloningBasedCreator{
EModelService模型=…;//已注入
MapApplication应用程序=…;//已注入
public void openNewWindow(){
MWindow originWindow=(MWindow)models.find(“the.main.window.id”,app);
MWindow newWindow=(MWindow)models.cloneElement(originWindow,null);
MPerspectiveStack新建透视堆栈=
(MPerspectiveStack)models.find(the.main.perspective.stack.id,newWindow);
setParent((MElementContainer)newWindow);
addTo(应用程序,新窗口);
//克隆共享元素。如果我们不这样做,渲染将在某个地方进行
//在兔子洞的深处抛出断言错误,因为
//查找元素失败,因为搜索根为null。
对于(最终MUIElement originSharedElement:originWindow.getSharedElements()){
最终MUIElement clonedSharedElement=models.cloneElement(originSharedElement,null);
setParent((MElementContainer)newWindow);
newWindow.getSharedElements().add(clonedSharedElement);
}
cloneSnippets(应用程序、originWindow、newPerspectiveStack、newWindow);
setContext(createContextForNewWindow(originWindow,newWindow));
newWindow.setToBerndered(true);
newWindow.setVisible(true);
newWindow.setOnTop(true);
型号:bringToTop(新窗口);
}
@SuppressWarnings({“rawtypes”,“unchecked”})
私有void addTo(MElementContainer目标,MUIElement子级){
setParent(目标);
target.getChildren().add(child);
}
/**
*克隆作为透视图的每个片段并添加克隆的透视图
*进入主透视堆栈。
*/
专用void cloneSnippets(地图应用程序,MWindow originWindow,
MPerspectiveStack新透视堆栈,MWindow新窗口){
布尔值isFirstSnippet=true;
for(MUIElement snippet:app.getSnippets()){
if(忽略代码段(代码段)){
继续;
}
字符串snipetId=snippet.getElementId();
MPerspective clonedpropective=
(MPerspective)模型。cloneSnippet(应用程序,snipetId,原始窗口);
查找PlaceHolders和CloneReferencedParts(克隆透视图、新窗口);
addTo(newPerspectiveStack,clonedPerspective);
if(isFirstSnippet){
newPerspectiveStack.setSelectedElement(clonedPerspective);
isFirstSnippet=false;
}
}
}
专用布尔值IgnoreSippet(MUIElement snippet){
return!(MPerspective的片段实例);
}
private void FindPlaceHolders和CloneReferencedParts(MPerspective clonedPerspective,MWindow newWindow){
列表占位符=
findElements(clonedPerspective,null,MPlaceholder.class,null);
for(MPlaceholder占位符:占位符){
MUIElement reference=placeholder.getRef();
如果(引用!=null){
placeholder.setRef(models.cloneElement(placeholder.getRef(),null));
占位符.getRef().setParent((MElementContainer)newWindow);
}
}
}
}
这段代码实际上不起作用,我们需要一些提示/建议 这是正确的,因为缺乏官方文件。开放的问题有:

  • 我们是否需要克隆共享对象?如果不需要,我们如何防止 渲染过程中出现错误)
  • 我们只看到克隆元素所在的代码 通过
    getChildren().add()
    添加到父级,但我们发现 子项不能自动获取父项,但父项为
    null
    。这是最重要的吗 将父对象也添加到子对象的模式是否正确
  • 我们有很深的感受 我们做得不对。我们在这里做的事情看起来太复杂了。是 有更简单/更好的方法吗

  • 您可以使用
    EModelService
    cloneSnippet
    方法执行此操作

    在Application.e4xmi的
    Snippets
    部分中设计
    MTrimmedWindow
    (或您想要的任何类型的窗口)。确保选中了要渲染的
    可见的
    标志。您可能需要设置宽度和高度边界(并且可能还需要设置x和y位置)

    创建新窗口的命令处理程序简单如下:

    @Execute
    public void execute(EModelService modelService, MApplication app)
    {
      MTrimmedWindow newWin = (MTrimmedWindow)modelService.cloneSnippet(app, "id of the snippet", null);
    
      app.getChildren().add(newWin);
    }
    

    我发现了那个问题,可能是重复的。我希望在提供一些示例sou时得到更详细的答案
    @Execute
    public void execute(EModelService modelService, MApplication app)
    {
      MTrimmedWindow newWin = (MTrimmedWindow)modelService.cloneSnippet(app, "id of the snippet", null);
    
      app.getChildren().add(newWin);
    }