I'm trying to modify the GWT 2.1 HelloMVP example code to use a more complex UI. (I'm not allowed to provide the link due to a two link limit)
My problem is that ActivityManager.setDisplay only accepts objects that implement AcceptsOneWidget. LayoutPanel and other ComplexPanel's don't implement AcceptsOneWidget. The example code uses a SimplePanel instead. But I can't seem to nest complex Widgets within the SimplePanel (they don't display).
I've found a few discussions on this problem:
People suggest the solution is to create a subclass of the ComplexPanel I want that implements the AcceptsOneWidget interface. Like so:
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;
}
}
}
This sounds great but it doesn't seem to work for me. Perhaps because I'm using GWT 2.3 instead of 2.1 or 2.2. In my EntryPoint I expect to simply replace the SimplePanel with my new PanelForView class and have the app run as before. Like so:
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();
}
}
This compiles fine but when I run it, I see nothing but a blank screen now. Is there something extra I have to do to initialize a ComplexPanel? Am I just misunderstanding something? I've tried adding Widgets and calling setSize to no avail. This is my first GWT project.
Thanks for your time.
Corey
You should be able to easily use a SimplePanel (or Composite subclass the implement AcceptsOneWidget). The best way to do this is to Think about the containing widget. You can add a: HTMLPanel, FlowPanel, VerticalPanel, etc into the one widget area of SimplePanel.
However, once you do this, you are bending the intended use of ActivityMapper/AcceptsOneWidget/SimplePanel
You can either create a more complex ui by:
Adding another ActivityMapper (with a different UI region - SimplePanel - which should change from Place to Place) or Adding a Widget area (that doesn't change from Place to Place)
or*
Have your Activity control the more complex view (keep the ActivityMapper.setDisplay widget a SimplePanel - but then have the Activity set an HTMLPanel, VerticalPanel, etc)
A very popular implementation is to keep a SimplePanel as the content area for the ActivityMapper. Then use UiBinder (with HTMLPanel as the top level element)
We can call the UiBinder: "view" and it can have many regions
All of these different elements are wrapped into view which can be a Composite
and then, in your