开发者

How can I use a ComplexPanel with a GWT ActivityManager

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:

http://www.google.com/url?sa=D&q=https://stackoverflow.com/questions/5143196/is-there-a-acceptsonewidget-which-also-providesresze-other-than-scrollpanel%3Fanswertab%3Dactive%23tab-top

http://www.google.com/url?sa=D&q=http://www.tempura.org/rants/2010/10/using-layoutpanels-with-gwt-2-1s-activitymanager/

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 activit开发者_高级运维yManager = 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

view.getTopArea() - SimplePanel, view.getLeft() - FlowPanel, view.getNameArea - Anchor/InlineHTML

All of these different elements are wrapped into view which can be a Composite

and then, in your

activity.start(AcceptsOneWidget panel){
 panel.setWidget(view);//insert your complex view into the SimplePanel view
  ...
}


Ok, so when I was having this problem I was just experimenting with the very simple UI that comes with the sample app.

I also tried keeping the SimplePanel and having the Activity return a HeaderPanel consisting of a label and an image (the second method mentioned in Ashton's Answer). I thought this didn't work. And I saw comments in blogs and forums that seemed to indicate this doesn't work. But once I started actually building up the UI with a DockPanel and nested TabPanel, etc., all of the sudden everything started displaying properly. I don't know why. It was probably a bug in my code I suppose. But I'm on my way now. I don't care to go back and diagnose exactly what went wrong. :)

Thanks for the advice guys!

Corey


Use RootLayoutPanel instead of RootPanel

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜