在包含ClientBundle的成员中使用ClientBundle是否可以?

时间:2013-12-04 17:54:07

标签: java gwt clientbundle

在我的应用中,我有MyAppResources,主要包含应用的自定义样式。我正在考虑将自定义样式应用于标准窗口小部件(例如CellTable)以及布局和自定义窗口小部件上的自定义样式的好方法是什么?

我的问题: 由于MyAppResources是一个单例(它不必如其他帖子中所述),但CellTableResources不是,CellTableResources是此实例的成员,该实例也是一个扩展的接口{ {1}},是否会在每个ClientBundle上创建代理'CellTableResources'?

如果是这样,我可以创建一个MyAppResources.INSTANCE.cellTableResources().foo()来解决这个问题吗?或者代理的创建是否可以忽略不计,即使有大量的MyAppResources.CELLTABLE_RESOURCE_INSTANCE来电?

其次,更多讨论问题:在这种情况下,使用多个MyAppResources.INSTANCE.cellTableResources().#的最佳做法是什么?我应该单独使用ClientBundle(从CellTableResources中删除它),在需要它的小部件中使用MyAppResources(或使用像我GWT.create(CellTableResources.class);那样的单例)?< / p>

MyAppResources

MyAppResources

public interface MyAppResources extends ClientBundle { public static final MyAppResources INSTANCE = GWT.create(MyAppResources.class); @Source("MyAppStyles.css") public MyAppCssResource css(); public CellTableResources cellTableResources(); }

CellTableResources

感谢您的阅读。

1 个答案:

答案 0 :(得分:2)

多部分问题,所以我将尝试分几个部分:

GWT.create()的费用是多少?

大多数GWT类都是'魔术',你不能用其他方式为自己写的东西,因为他们要求编译器为你填写具体的细节。在开发模式下运行与编译为JS时,这些通常是不同的。

GWT.create的情况下,事实证明这是编译到new - 它仅用于创建新实例。那么新实例与单身实体的成本是多少?这完全取决于正在创建的对象。如果对象中没有字段,那么成本基本上是免费的 - 事实上,编译器可能会选择实际删除构造函数调用,并且无论如何都要将所有后续方法重写为static

在大多数情况下会发生这种情况 - GWT.create应该被认为是非常便宜的,除非你做了一些愚蠢的事情,比如在一个多次运行的循环中调用它。

当我在另一个ClientBundle内列出ClientBundle方法时会发生什么?

那么,当您在ClientBundle中列出任何时会发生什么?

ClientBundle中列出的任何内容都必须使用@ResourceGeneratorType进行注释,以指示如何生成该类型。例如,这里是ImageResource

/**
 * Provides access to image resources at runtime.
 */
@DefaultExtensions(value = {".png", ".jpg", ".gif", ".bmp"})
@ResourceGeneratorType(ImageResourceGenerator.class)
public interface ImageResource extends ResourcePrototype {
//...

它会根据需要调用ImageResourceGenerator来创建图像。该注释中描述的任何类都必须实现com.google.gwt.resources.ext.ResourceGenerator,其中描述了如何准备工作,如何创建必要的字段,如何初始化它们以及如何完成。

那么ClientBundle本身的情况如何呢?查看com.google.gwt.resources.rg.BundleResourceGenerator - 这是一个非常简单的类,只需对给定方法的类型调用GWT.create()。所以,可预测的,这意味着那些'子'ClientBundle是通过GWT.create创建的,或多或少与你可能做的一样。

好的,这在具体案例中意味着什么?

事实证明,ClientBundles实例没有跟踪新创建对象的字段,而是使用他们使用的静态成员 - 实际上是单例。这意味着一旦您调用了一次方法,它返回的实例将与您下次调用它时创建的实例相同。具有相同内容的两个不同的ClientBundle当然会保留两个不同的对象副本,但是创建ClientBundle的次数并不重要 - 它的内部结构将始终相同。

还有别的吗?

是的!请记住,您在这里处理的是接口,而不是类,因此您实际上可以多次扩展一次!

public interface MyAppResources extends 
       ClientBundle, 
       CellTable.Resources, 
       CellTree.Resources {//etc
  //...

现在,如果两个接口描述相同的方法,您可能会遇到问题,但如果没有,这可以在生成sprited图像时提供优势。每个人ClientBundle在准备使用时都会使用自己的图像池 - 如果ClientBundle中有ClientBundle,他们将无法合作将图像拼凑成更大的图像。为此,您只需制作一个ClientBundle类型。这在你的特定情况下可能无关紧要,但我认为这也值得一提。