如何将ComplexPanel与GWT ActivityManager一起使用
我试图修改GWT2.1HellomVP示例代码,以使用更复杂的UI。(由于双链接限制,我不允许提供链接) 我的问题是ActivityManager.setDisplay只接受实现AcceptsOneWidget的对象。LayoutPanel和其他ComplexPanel不实现AcceptsOneWidget。示例代码改用SimplePanel。但我似乎无法在SimplePanel中嵌套复杂的小部件(它们不显示) 我发现了一些关于这个问题的讨论: 人们建议解决方案是创建我想要的ComplexPanel的子类,该子类实现AcceptsOneWidget接口。像这样:如何将ComplexPanel与GWT ActivityManager一起使用,gwt,gwt-2.3,Gwt,Gwt 2.3,我试图修改GWT2.1HellomVP示例代码,以使用更复杂的UI。(由于双链接限制,我不允许提供链接) 我的问题是ActivityManager.setDisplay只接受实现AcceptsOneWidget的对象。LayoutPanel和其他ComplexPanel不实现AcceptsOneWidget。示例代码改用SimplePanel。但我似乎无法在SimplePanel中嵌套复杂的小部件(它们不显示) 我发现了一些关于这个问题的讨论: 人们建议解决方案是创建我想要的ComplexP
public class PanelForView extends LayoutPanel implements AcceptsOneWidget {
IsWidget myWidget = null;
@Override
public void setWidget(IsWidget w) {
if (myWidget != w) {
if (myWidget != null) {
remove(myWidget);
}
if (w != null) {
add(w);
}
myWidget = w;
}
}
}
public class HelloMVP implements EntryPoint {
private Place defaultPlace = new HelloPlace("World!");
// private SimplePanel appWidget = new SimplePanel(); // Replace this with PanelForView
private PanelForView appWidget = new PanelForView(); // This compiles but doesn't work.
// private SimpleLayoutPanel appWidget = new SimpleLayoutPanel(); // This doesn't work either.
public void onModuleLoad() {
// Create ClientFactory using deferred binding so we can replace with different
// impls in gwt.xml
ClientFactory clientFactory = GWT.create(ClientFactory.class);
EventBus eventBus = clientFactory.getEventBus();
PlaceController placeController = clientFactory.getPlaceController();
// Start ActivityManager for the main widget with our ActivityMapper
ActivityMapper activityMapper = new AppActivityMapper(clientFactory);
ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);
activityManager.setDisplay(appWidget);
// Start PlaceHistoryHandler with our PlaceHistoryMapper
AppPlaceHistoryMapper historyMapper= GWT.create(AppPlaceHistoryMapper.class);
PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
historyHandler.register(placeController, eventBus, defaultPlace);
RootPanel.get().add(appWidget);
// Goes to place represented on URL or default place
historyHandler.handleCurrentHistory();
}
}
这听起来不错,但似乎对我不起作用。可能是因为我使用的是GWT2.3,而不是2.1或2.2。在我的入口点中,我希望用我的新PanelForView类简单地替换SimplePanel,并让应用程序像以前一样运行。像这样:
public class PanelForView extends LayoutPanel implements AcceptsOneWidget {
IsWidget myWidget = null;
@Override
public void setWidget(IsWidget w) {
if (myWidget != w) {
if (myWidget != null) {
remove(myWidget);
}
if (w != null) {
add(w);
}
myWidget = w;
}
}
}
public class HelloMVP implements EntryPoint {
private Place defaultPlace = new HelloPlace("World!");
// private SimplePanel appWidget = new SimplePanel(); // Replace this with PanelForView
private PanelForView appWidget = new PanelForView(); // This compiles but doesn't work.
// private SimpleLayoutPanel appWidget = new SimpleLayoutPanel(); // This doesn't work either.
public void onModuleLoad() {
// Create ClientFactory using deferred binding so we can replace with different
// impls in gwt.xml
ClientFactory clientFactory = GWT.create(ClientFactory.class);
EventBus eventBus = clientFactory.getEventBus();
PlaceController placeController = clientFactory.getPlaceController();
// Start ActivityManager for the main widget with our ActivityMapper
ActivityMapper activityMapper = new AppActivityMapper(clientFactory);
ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);
activityManager.setDisplay(appWidget);
// Start PlaceHistoryHandler with our PlaceHistoryMapper
AppPlaceHistoryMapper historyMapper= GWT.create(AppPlaceHistoryMapper.class);
PlaceHistoryHandler historyHandler = new PlaceHistoryHandler(historyMapper);
historyHandler.register(placeController, eventBus, defaultPlace);
RootPanel.get().add(appWidget);
// Goes to place represented on URL or default place
historyHandler.handleCurrentHistory();
}
}
这编译得很好,但当我运行它时,我看到的只是一个空白屏幕。初始化ComplexPanel需要做些额外的事情吗?我只是误解了什么吗?我尝试过添加小部件并调用setSize,但没有效果。这是我的第一个GWT项目
谢谢你抽出时间
Corey您应该能够轻松地使用SimplePanel(或ImplementAcceptsOneWidget的复合子类)。实现这一点的最佳方法是考虑包含的小部件。您可以在SimplePanel的一个小部件区域中添加:HTMLPanel、FlowPanel、VerticalPanel等 但是,一旦执行此操作,您就改变了ActivityMapper/AcceptsOneWidget/SimplePanel的预期用途 您可以通过以下方式创建更复杂的ui: 添加另一个ActivityMapper(具有不同的UI区域-SimplePanel-应该在不同的地方更改)或添加小部件区域(不会在不同的地方更改) 或* 让您的活动控制更复杂的视图(将ActivityMapper.setDisplay小部件保持为SimplePanel,然后将活动设置为HTMLPanel、VerticalPanel等) 一个非常流行的实现是保留SimplePanel作为ActivityMapper的内容区域。然后使用UiBinder(HTMLPanel作为顶级元素) 我们可以将UiBinder称为“视图”,它可以有许多区域
view.getTopArea() - SimplePanel, view.getLeft() - FlowPanel, view.getNameArea - Anchor/InlineHTML
所有这些不同的元素都被包装到视图中,视图可以是一个复合视图
然后,在你的
activity.start(AcceptsOneWidget panel){
panel.setWidget(view);//insert your complex view into the SimplePanel view
...
}
好的,所以当我遇到这个问题时,我只是在试验示例应用程序附带的非常简单的UI 我还尝试保留SimplePanel,让活动返回一个由标签和图像组成的HeaderPanel(Ashton回答中提到的第二种方法)。我以为这没用。我在博客和论坛上看到的评论似乎表明这是行不通的。但一旦我开始用DockPanel和嵌套的TabPanel等构建UI,所有的东西都开始正常显示。我不知道为什么。我想这可能是我代码中的一个bug。但我在路上。我不想回去准确地诊断出哪里出了问题。:) 谢谢你们的建议,伙计们
Corey使用RootLayoutPanel而不是RootPanel尝试删除if语句
if(myWidget!=w)
谢谢Ashton,你提到的第二种方法是我最初想到的。但我也要考虑第一个问题。你能详细说明为什么要这样做吗?