GWT app UI不会显示

时间:2012-11-23 18:01:51

标签: java gwt uibinder

我已经实现了一个简单的GWT应用程序,该应用程序使用1个Place和1个Activity(我已经将其作为Presenter实现,扩展了AbstractActivity并且包含Composite“view”子类。视图中唯一的UI对象是GWT-Bootstrap NavBar,我希望在我的“主页”顶部显示。

我在Eclipse内部运行应用程序,并没有收到任何编译器或运行时错误。当我转到开发模式控制台指向我的URL时,我在浏览器中稍微暂停(我假设这是浏览器“下载”JavaScript),然后我看到一个空白的白色屏幕(而不是我的NavBar)。窗口标题是正确的(我在模块的HTML页面中设置它),当我查看源代码时,我看到相同的HTML源代码,所以我知道应用程序的JavaScript正在正确地进入浏览器。它只是不渲染NavBar。

我在System.out.println(),我的默认onModuleLoad()ActivityManagerActivityMapper,演示者和观看PlaceHistoryMapper以及所有Composite中散布了sysout个语句这些PlaceHistoryHandler#handleCurrentHistory语句在开发控制台中打印;告诉我,我已将所有内容正确连接在一起,并且在运行时调用onModuleLoad方法时(从gwt-bootstrap内部),我应该看到我的NavBar。

我能想到的唯一可能性是:

  1. 我错误地配置了RootLayoutPanel;或
  2. 我没有正确使用UiBinder
  3. 我使用“活动和地方”的方式还有其他问题,或者我将{ui}附加到onModuleLoad()内的gwt-bootstrap
  4. 至于UiField

    • 我将JAR放在我项目的类路径上(我知道这一点,因为当我在我的小部件/视图中包含NavBar类型的新<inherits name="com.github.gwtbootstrap.Bootstrap"/>时,我没有得到任何编译器错误)
    • 我将public class WebRootDisplay extends BaseDisplay { private static WebRootDisplayUiBinder uiBinder = GWT .create(WebRootDisplayUiBinder.class); interface WebRootDisplayUiBinder extends UiBinder<Widget, WebRootDisplay> { } @UiField Navbar navBar; public WebRootDisplay(EventBus eventBus) { super(eventBus); System.out.println("I get this printing to the console at runtime."); initWidget(uiBinder.createAndBindUi(this)); System.out.println("...and this too!"); } } <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:b="urn:import:com.github.gwtbootstrap.client.ui"> <g:HTMLPanel> <b:Navbar ui:field="navBar"> <b:Nav> <b:NavLink href="http://www.google.com"> Home </b:NavLink> </b:Nav> </b:Navbar> </g:HTMLPanel> </ui:UiBinder> 添加到我的GWT模块XML

    所以,如果我还有其他配置,请告诉我!

    至于UiBinder的东西,这是我的小部件/视图:

    NavBar

    我注意到的一件事是我在UiBinder XML中的HTMLPanel内有Composite。我之所以这样做是因为我使用Google-Eclipse插件为我生成了一个新的UiBinder(它自动生成了BaseDisplay(然后我修改为扩展Composite,它本身扩展了HTMLPanel)以及UiBinder片段。我想GWT希望我把所有的UI字段放在这个NavBar ...(?)

    如果我在这里遗漏任何东西,请告诉我。我没有实例化createAndBindUi字段,因为我相信这就是gwt-bootstrap对我的所作所为。

    如果我的onModuleLoad配置和我对UiBinder的使用看起来都是正确的,那么其他一些东西显然是错误的,我将不得不发布更多代码。我只想在排除前两项之前暂时搁置。提前谢谢!

    更新

    以下是public void onModuleLoad() { // Some homegrown DI stuff. I have verified that the injector works properly. ApplicationScope appScope = new ApplicationScope(); setInjector(new ApplicationInjector(appScope, InjectorProvider.newMasterProvider())); // Add the sole composite child to the RootLayoutPanel. // I have verified that injectWebRootDisplay returns a fully configured // WebRootDisplay instance. RootLayoutPanel.get().add(injector.injectWebRootDisplay()); historyHandler.register(placeController, eventBus, defaultPlace); historyHandler.handleCurrentHistory(); }

    {{1}}

4 个答案:

答案 0 :(得分:0)

您可以粘贴代码的onModuleLoad()部分吗?

如果您没有任何Exception和错误消息,我认为您应该检查是否正确地将视图添加到RootPanel,或者当您运行该应用时,您应该检查{ {1}} view中的div中存在{1}},并且只是看不见或类似。

HTML部分看起来很好看。

修改 这个UiBinder对我说的不多,但你可以尝试一下。 我总是以下列方式使用RootLayoutPanel.get()方法:

onModuleLoad()

因此,我总是向占位符RootLayoutPanel.get("someDivId").add(injector.injectWebRootDisplay()); 添加divtable并添加HTML,因此您可以在获得RootPanel时引用该div。我不确定这是必要的,但我第一次看到这个,它正常工作。 如果您有任何疑问或问题,请告诉我。 :)

答案 1 :(得分:0)

好吧,我已经尝试了一个与您的代码完全相同的本地示例,我认为该问题不在UI绑定器中。到目前为止,您提供的代码是正确的,因此错误很可能是在其他地方。

最大的嫌疑人是BaseDisplay级。据我所知,这个类不是来自GWT或gwt-bootstrap。您可以通过更改WebRootDisplay类来快速检查它,因此它扩展了经典的GWT Composite类,而不是BaseDisplay(并禁用所有mvp内容)。如果有效,您可以证明问题是由&#39; BaseDisplay&#39;

引起的

由于我没有完整的代码,我只能假设WebRootDisplay也用于显示视图,而且最有可能的错误是当视图添加到该类时,之前已添加小部件(在您的情况下,它是您在WebRootDisplay的构造函数中添加的NavBar)将被删除。最有可能的问题应该是方法setWidgetinitWidget

答案 2 :(得分:0)

根据我对GWT活动和地点的体验,空白页面的常见罪魁祸首是没有使用PlaceHistoryMapper注册Place的Tokenizer:

/**
 * PlaceHistoryMapper interface is used to attach all places which the
 * PlaceHistoryHandler should be aware of. This is done via the @WithTokenizers
 * annotation or by extending PlaceHistoryMapperWithFactory and creating a
 * separate TokenizerFactory.
 */
@WithTokenizers({
    MyPlace.Tokenizer.class,
    SomeOtherPlace.Tokenizer.class})
public interface AppPlaceHistoryMapper extends PlaceHistoryMapper {}

请参阅https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces#PlaceHistoryMapper

白页的另一个原因(特别是在单个地方使用RootLayoutPanel.get()时,无法在ActivityMapper中正确映射地点:

/**
 * AppActivityMapper associates each Place with its corresponding
 * {@link Activity}
 * 
 * @param clientFactory
 *            Factory to be passed to activities
 */
public class AppActivityMapper implements ActivityMapper {
    private ClientFactory clientFactory;

    public AppActivityMapper(ClientFactory clientFactory) {
        super();
        this.clientFactory = clientFactory;
    }

    @Override
    public Activity getActivity(Place place) {
        if (place instanceof MyPlace)
            return new MyActivity((MyPlace) place, clientFactory);
        else if (place instanceof SomeOtherPlace)
            return new SomeOtherActivity((SomeOtherPlace) place, clientFactory);

        return null; // If your return null with single place bound to RootLayoutPanel
        // you may get a blank white page
    }
}

请参阅https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces#ActivityMapper

如果没有更完整的代码示例,就无法确切地确定发生了什么,但上面列出的两个原因是常见的疏忽,可能会帮助遇到此线程的任何人。

答案 3 :(得分:-1)

而不是System.println使用GWT.log消息。然后打开Javascript控制台(Firebug或Chrome)并查看代码的最终位置。 GWT.log将在浏览器控制台中打印出来,因此您可以看到编译的JS代码的作用。

此外,如果您使用漂亮模式进行编译,您将在浏览器中看到生成的Javascript代码,并能够单步执行并查看被调用的内容。