在RCP应用程序中,我如何以编程方式定义和打开新窗口? 我想打开几个窗口 - 每个窗口显示不同的数据。如何为每个窗口设置不同的输入?
我想模拟Eclipse IDE的相同功能(Window - > New Window),但我希望每个新打开的窗口都有不同的输入。我正在尝试使用: IWorkbenchPage newPage = window.openPage(inputObject); 如何以编程方式定义标识窗口中显示的数据的“inputObject”?
答案 0 :(得分:4)
Eclipse术语中的工作台窗口是一个窗口,通常包含菜单,工具栏,编辑器区域和视图。 Eclipse RCP应用程序通常包含单个窗口,但某些应用程序允许创建多个窗口。例如,在Eclipse IDE中,可以通过从窗口菜单中选择“新窗口”来打开另一个窗口。透视图可以独立设置到每个窗口中。
虽然多个窗口可能令人困惑,但它们也非常有用。例如,如果用户可能正在处理两个不同的数据源,但是对每个数据源打开了多个编辑器和视图,那么打开两个窗口会很有用。通过打开RCP应用程序的两个实例可以实现相同的效果。但是,这需要加载多个代码副本和其他资源,这需要为每个数据源完全初始化应用程序,这会使窗口之间的交叉通信变得更加困难。
要允许RCP应用程序的用户打开另一个窗口,您有两种选择。
您可以在RCP应用程序中包含“新窗口”菜单项。这可以通过向RCP应用程序添加工作台提供的操作来完成。修改ActionBarAdvisor类:
添加到字段声明:
private IWorkbenchAction newWindowAction;
添加到您执行操作的代码(通常是名为makeActions的方法):
newWindowAction = ActionFactory.OPEN_NEW_WINDOW.create(window);
register(newWindowAction);
添加到您创建菜单的代码中:
menu.add(newWindowAction);
其中菜单通常是“窗口”菜单。如果您的应用程序中还没有Window菜单,并且想要创建一个,则以下行将起作用:
MenuManager菜单=新的MenuManager( “&安培;窗口”, IWorkbenchActionConstants.M_WINDOW);
这将为您提供一个菜单项,它将以与Eclipse IDE中的Window-> New Window菜单项相同的方式创建一个新窗口。
然而,这无法控制输入。第二个窗口可能有一组不同的视图和编辑器打开,并且可能有不同的透视图集,但它仍然具有相同的“输入”。例如,在Eclipse IDE中,您可以打开第二个窗口,但如果切换工作区,那么这将适用于所有窗口。
创建新窗口的第二种方法是通过创建页面以编程方式执行此操作。这允许您为窗口设置“输入”。因此,在一个窗口中打开视图可能会导致显示的数据与在另一个窗口中打开相同视图时不同。
从技术上讲,窗口没有输入。页面有输入。一个窗口最多只能包含一页。在某些方法名称中可能看起来一个窗口可以有多个页面(例如getActivePage意味着存在非活动页面)。当支持多个页面时,这些方法名称是Eclipse 2.0天的延续。
以编程方式打开新页面:
IWorkbenchPage newPage = window.openPage(myInput);
如果窗口尚未包含页面,此方法将在给定窗口中创建新页面,否则将创建一个包含页面的新窗口。
如果您支持多个具有不同输入的窗口,那么您应该在每个窗口中设置一个区分每个窗口的标题:
newPage.getWorkbenchWindow().getShell().setText("My App - " + myInput.getName());
在某些情况下,您可能希望将输入更改为窗口。您无法更改页面的输入,因此必须通过关闭现有页面并创建新页面来完成此操作。以下代码将关闭现有页面:
IWorkbenchPage activePage = window.getActivePage();
activePage.close();
请注意,Eclipse提供的某些视图使用页面输入。例如,Common Navigator视图将使用页面输入作为导航树的根元素。
要从您自己的视图访问页面输入,请致电site.getPage().getInput()
。如果您没有要开始的站点上下文,则调用以下内容将获得输入:
PlatformUI.getWorkbench()getActiveWorkbenchWindow()getActivePage()getInput();
请注意,'input'是一个Object。它可以是你喜欢的任何课程的对象。当你从Page::getInput()
取回它时,将其强制转换回相应的类。您通常不应该创建一个新类作为输入。您几乎总能使用现有的类。这通常是对象模型的顶级对象。除了存储它之外,Eclipse框架对此输入不执行任何操作,并在调用Page::getInput()
时将其传回。
答案 1 :(得分:2)
您需要了解如何在Eclipse插件模型中实现视图。这可以通过添加扩展点和配置属性或通过代码来实现。配置属性是首选方法。两者都解释如下:
http://www.vogella.de/articles/RichClientPlatform/article.html#views
该网站有很多关于Eclipse开发的好文章:
http://www.vogella.de/eclipse.html
无论如何,正如PSU_Kardi建议的那样,阅读整篇文章是个好主意。
答案 2 :(得分:1)
我认为你需要为我或其他人更好地定义一个“窗口”来回答这个问题。
您是否正在创建一个想要多次打开的插件,在这种情况下,您可能需要一个编辑器并且需要确保您没有使用Singleton模式 - 您可以在清单文件中指定
或者您是否正在尝试创建要显示数据的窗口?像一个视图?如果您这样做,您将需要了解如何创建ViewPart并确保正确扩展所有内容。
我建议去我最喜欢的两个RCP网站
http://www.vogella.de/articles/RichClientPlatform/article.html
http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/CatalogSWT-JFace-Eclipse.htm
答案 3 :(得分:1)
你应该确保你真的想打开一堆其他窗口。也许你可以通过在现有窗口中打开一些新的视图或编辑器来实现同样的目的?使用多个视图通常更容易让用户理解,因为它们没有呈现几个看起来几乎相同的窗口。它还使您更容易显示视图之间的关系。
话虽这么说,你可以致电IWorkbench.openWorkbenchWindow
来创建一个全新的窗口。一个很好的例子是Window的代码 - >新窗口,位于OpenNewWindowMenu。
答案 4 :(得分:1)
以下处理程序-每次调用其@Execute方法时-创建一个新的TrimmedWindow,其数据内容彼此独立:
package com.vogella.tasks.ui.handlers;
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.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.model.application.ui.basic.impl.TrimmedWindowImpl;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import com.vogella.tasks.ui.parts.DynamicPart;
public class OpenAdditionalWindowHandler {
private static final String PART_DESCRIPTOR_ID = "com.vogella.tasks.ui.partdescriptor.static.part";
static int posX = 20;
static int posY = 20;
static int counter = 0;
/**
* Opens a new TrimmedWindow based on the (template) definition. Each time invoked a separate window is opened with independent data content.
*/
@Execute
public void execute(EPartService partService, MWindow window, MApplication application, EModelService modelService) throws WorkbenchException {
// Get the predefined TrimmedWindow and clone it
MUIElement element = modelService.find("com.vogella.tasks.ui.trimmedwindow.zusatz", application);
TrimmedWindowImpl clonedWindow = (TrimmedWindowImpl) modelService.cloneElement(element, application);
application.getChildren().add(clonedWindow);
modelService.bringToTop(clonedWindow);
clonedWindow.setToBeRendered(true);
// Shift the new windows a little bit each time a new one is created
shiftWindowPositionSoTheyDontExactlyOverlay(clonedWindow);
// Derive new Part Descriptor Id with counter & create new part
final String dynamicallyCreatedPartId = PART_DESCRIPTOR_ID + counter++;
MPart dynamicallyCreatedPart = partService.createPart(PART_DESCRIPTOR_ID);
if (dynamicallyCreatedPart != null) {
// Add the part to the newly cloned trimmed window
clonedWindow.getChildren().add(dynamicallyCreatedPart);
dynamicallyCreatedPart.setElementId(dynamicallyCreatedPartId);
dynamicallyCreatedPart.setLabel("My part nbr " + counter);
final DynamicPart staticPseudoAspect = (DynamicPart) dynamicallyCreatedPart.getObject();
staticPseudoAspect.setContent("Dynamic part content nbr " + counter);
clonedWindow.getChildren().get(0).setVisible(true);
clonedWindow.getChildren().get(0).setToBeRendered(true);
}
}
private void shiftWindowPositionSoTheyDontExactlyOverlay(TrimmedWindowImpl clonedWindow) {
posX = posX + 20;
posY = posY + 20;
clonedWindow.setX(posX);
clonedWindow.setY(posY);
}
}
“修剪”窗口在应用程序模型中定义为模板。与应用程序模型中以PartDescriptor形式描述的Part相同。
答案 5 :(得分:0)
这将在主应用程序窗口旁边打开一个新窗口:
public static String duplicate(String str) {
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for(int i=0; i<str.length(); i++) {
if(map.containsKey(str.charAt(i))) {
return str.charAt(i);
}
map.put(str.charAt(i), i);
}
return "-1";
}