【问题标题】:GWT app UI wont displayGWT 应用程序 UI 不会显示
【发布时间】:2012-11-23 18:01:50
【问题描述】:

我已经实现了一个简单的 GWT 应用程序,它使用 1 个地方和 1 个活动(我已经将其实现为一个演示者,它扩展了一个 AbstractActivity 并包含一个 Composite“视图”子类)。视图中的第一个也是唯一的 UI 对象是 GWT-Bootstrap NavBar,我希望将其显示在“主页”的最顶部。

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

我在整个onModuleLoad() 中添加了System.out.println() 语句,我的默认ActivityManagerActivityMapperPlaceHistoryMapper、演示者和视图Composite,所有这些sysout 语句都打印在开发控制台中;告诉我我已将所有内容正确连接在一起,并且在运行时调用PlaceHistoryHandler#handleCurrentHistory 方法时(从onModuleLoad 内部),我应该会看到我的导航栏。

我能想到的唯一可能是:

  1. 我的gwt-bootstrap配置错误;或
  2. 我没有正确使用 UiBinder
  3. 我使用“活动”和“地点”的方式有其他问题,或者我如何将 UI 附加到 RootLayoutPanel 内的 onModuleLoad() 有问题。

至于gwt-bootstrap

  • 我将 JAR 放在项目的类路径中(我知道这一点,因为当我在小部件/视图中包含 NavBar 类型的新 UiField 时,我没有收到任何编译器错误)
  • 我将<inherits name="com.github.gwtbootstrap.Bootstrap"/> 添加到我的 GWT 模块 XML 中

所以如果我还有什么需要配置的,请告诉我!

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

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>

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

如果我在这里遗漏了什么,请告诉我。我没有实例化 NavBar 字段,因为我相信这就是 createAndBindUi 为我所做的。

如果我的gwt-bootstrap 配置和我对 UiBinder 的使用看起来都是正确的,那么显然还有其他问题,我将不得不发布更多代码。我只是想在前两项被排除之前先推迟一下。提前致谢!

更新

这里是onModuleLoad

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

【问题讨论】:

    标签: java gwt uibinder


    【解决方案1】:

    您能粘贴代码中的onModuleLoad() 部分吗?

    如果您没有收到任何Exception 和错误消息,我认为您应该检查是否将视图正确添加到RootPanel,或者当您运行应用程序时,您应该检查view 是否存在在divHTML 中,只是不可见或类似的东西。

    UiBinder 部分乍一看还不错。

    编辑: 这个onModuleLoad() 并没有对我说太多,但你可以尝试一下。 我总是通过以下方式使用 RootLayoutPanel.get() 方法:

    RootLayoutPanel.get("someDivId").add(injector.injectWebRootDisplay());
    

    所以我总是将divtable 添加到占位符HTMLid,这样您就可以在获得RootPanel 时参考该div。我不相信这是必要的,但我第一次看到这个,它工作正常。 如果您有任何疑问或问题,请告诉我。 :)

    【讨论】:

    • 感谢@Endox (+1) - 请在原始问题底部查看我的更新。再次感谢!
    • 我认为您将 RootLayoutPanel 误认为是 RootPanel。 RootLayoutPanel 不允许您选择放置它的元素。它甚至没有get(String param) 方法=)
    【解决方案2】:

    好吧,我尝试了一个与您的代码完全一样的本地示例,我认为问题不在于 UI 活页夹。您到目前为止提供的代码是正确的,因此很可能错误出在其他地方。

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

    由于我没有完整的代码,我只能假设 WebRootDisplay 也用于显示视图,并且最有可能的错误是当视图添加到该类时,以前添加的小部件(在您的如果它是您在 WebRootDisplay) 的构造函数中添加的 NavBar,则会被删除。问题很可能出在方法setWidgetinitWidget

    【讨论】:

      【解决方案3】:

      根据我对 GWT 活动和地点的经验,空白页的一个常见罪魁祸首是未能将地点的标记器注册到 PlaceHistoryMapper:

      /**
       * 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

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

      【讨论】:

        【解决方案4】:

        使用 GWT.log 消息代替 System.println。然后打开 Javascript 控制台(Firebug 或 Chrome),看看你的代码在哪里结束。 GWT.log 将在浏览器控制台中打印出来,因此您可以看到编译后的 JS 代码做了什么。

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

        【讨论】:

        • 开发模式下对他不起作用。如何编译整个东西应该有帮助?
        • 编译 GWT 代码并单步执行它有时可以向您显示代码在哪里崩溃或无法调用您的代码。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-24
        • 1970-01-01
        • 2019-01-22
        • 1970-01-01
        • 2015-07-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多