如何将ComplexPanel与GWT ActivityManager一起使用

时间:2011-06-10 19:29:16

标签: gwt gwt-2.3

我正在尝试修改GWT 2.1 HelloMVP示例代码以使用更复杂的UI。 (由于链接限制,我不允许提供链接)

我的问题是ActivityManager.setDisplay只接受实现AcceptsOneWidget的对象。 LayoutPanel和其他ComplexPanel不实现AcceptsOneWidget。示例代码使用SimplePanel。但我似乎无法在SimplePanel中嵌套复杂的小部件(它们不显示)。

我发现了一些关于这个问题的讨论:

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/

人们建议解决方案是创建我想要的ComplexPanel的子类来实现AcceptsOneWidget接口。像这样:

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; 
         } 
     } 
} 

听起来不错,但似乎对我不起作用。也许是因为我使用的是GWT 2.3而不是2.1或2.2。在我的EntryPoint中,我希望简单地将SimplePanel替换为我的新PanelForView类,并让应用程序像以前一样运行。像这样:

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吗?我只是误解了什么吗?我尝试添加Widgets并调用setSize无济于事。这是我的第一个GWT项目。

感谢您的时间。

科里

3 个答案:

答案 0 :(得分:2)

您应该能够轻松地使用SimplePanel(或复合子类实现AcceptsOneWidget)。最好的方法是考虑包含小部件。您可以在SimplePanel的一个小部件区域中添加:HTMLPanel,FlowPanel,VerticalPanel等。

但是,一旦你这样做,你就会弯曲ActivityMapper / AcceptsOneWidget / SimplePanel的预期用途

您可以通过以下方式创建更复杂的ui:

添加另一个ActivityMapper(具有不同的UI区域 - SimplePanel - 应该从Place更改为Place)或添加Widget区域(不会从Place到Place更改)

或*

让Activity控制更复杂的视图(将ActivityMapper.setDisplay小部件保持为SimplePanel - 但然后让Activity设置HTMLPanel,VerticalPanel等)

一个非常流行的实现是将SimplePanel保留为ActivityMapper的内容区域。然后使用UiBinder(HTMLPanel作为顶级元素)

我们可以调用UiBinder:“view”,它可以有很多区域

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
  ...
}

答案 1 :(得分:0)

好的,所以当我遇到这个问题时,我只是试验了示例应用程序附带的非常简单的UI。

我还尝试保留SimplePanel并让Activity返回一个由标签和图像组成的HeaderPanel(Ashton的答案中提到的第二种方法)。我认为这不起作用。我在博客和论坛上看到的评论似乎表明这不起作用。但是,一旦我开始使用DockPanel和嵌套的TabPanel等构建UI,突然间一切都开始正常显示。我不知道为什么。我认为这可能是我的代码中的一个错误。但我现在正在路上。我不想回去确切地知道出了什么问题。 :)

感谢你的建议!

科里

答案 2 :(得分:0)

使用RootLayoutPanel而不是RootPanel