【发布时间】:2016-08-04 22:40:43
【问题描述】:
我们想要实现一个可能有多个窗口的 RCP 应用程序 (MWindow)
对于不同的数据。 Windows 必须是独立的(不像新的 Eclipse IDE
窗口菜单项),但必须可以从
一个窗口进入另一个窗口。想象一个像 Word 这样的应用程序,您可以在其中
打开多个文档。我们尝试了各种方法,但它很安静
很难找到正确的 e4 方式:
1。为每个窗口创建一个新的 E4Application
我们的第一个方法是为每个应用程序创建并运行一个全新的 E4Application
新窗户。但这听起来不是正确的 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());
这似乎不是正确的做法。
2。 Eclipse IDE 方法
在 Eclipse IDE 中,您可以转到菜单并单击 Window -> New Window
将打开一个全新的顶层窗口。但它是同步的:打开
两个窗口中的相同文本文件并在第一个窗口中编辑它会改变它
另一个也是。尽管我们通过简单地复制和粘贴来尝试这种方法
来自org.eclipse.ui.actions.OpenInNewWindowAction#run():
// Does not work because we do not have the RCP3 workbench in RCP4.
final IWorkbench workbench = PlatformUI.getWorkbench();
final IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
final IWorkbenchPage activePage = workbenchWindow.getActivePage();
final String perspectiveId;
if (activePage != null && activePage.getPerspective() != null) {
perspectiveId = activePage.getPerspective().getId();
} else {
perspectiveId = workbenchWindow.getWorkbench().getPerspectiveRegistry().getDefaultPerspective();
}
workbenchWindow.getWorkbench().openWorkbenchWindow(perspectiveId, null);
Eclipse IDE 似乎使用了 RCP3 兼容层。我们没有
找到了获取IWorkbench 对象的方法。既不由
PlatformUI#getWorkbench(),也不是通过应用程序上下文,也不是包
上下文。
3。克隆主窗口
我们偶然发现了Opening multiple instances of an MTrimmedWindow complete with perspectives etc 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);
}
}
}
}
这段代码真的不起作用,我们真的需要一些提示/建议如何去做 没错,因为缺乏官方文件。开放的问题是:
- 我们是否需要克隆共享对象,如果不需要,我们如何防止 渲染过程中的错误)?
- 我们只看到了克隆元素所在的代码
通过
getChildren().add()添加到父级,但我们发现 孩子不会自动获得父母,但它是null。是不是 将父母也添加到孩子的正确模式? - 我们深有感触 我们这样做是不对的。我们在这里做的事情看起来太复杂了。是 有更简单/更好的方法吗?
【问题讨论】:
-
我找到了这个问题。我希望在提供一些示例源时得到更详细的答案。
标签: java eclipse eclipse-rcp e4