0

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

我的问题:由于 MyAppResources 是一个单例(它不一定是,如其他帖子中所述),但CellTableResources不是,并且CellTableResources是此实例的成员,它也是一个接口也在扩展ClientBundle,代理“CellTableResources”是否会成为在每个MyAppResources.INSTANCE.cellTableResources().foo()?

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

ClientBundle其次,更多的是一个讨论问题:在这种情况下使用多个 s 的最佳实践是什么?我是否应该CellTableResources单独使用(从 中删除它MyAppResources),GWT.create(CellTableResources.class);在需要它的小部件中使用(或使用像我一样的单例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

public interface CellTableResources extends CellTable.Resources {

    interface CellTableStyle extends CellTable.Style {
    }

    @Override
    @Source({ CellTable.Style.DEFAULT_CSS, "CellTableStyles.css" })
    CellTableStyle cellTableStyle();

    @Source("green_light.png")
    ImageResource getGreenLight();

    //...
}

感谢您的阅读。

4

1 回答 1

2

多部分问题,所以我将尝试分几个部分来解决这个问题:

费用是GWT.create()多少?

大部分GWT课程都是“魔术”,您无法以其他方式为自己编写的东西,因为它们要求编译器为您填写特定细节。在开发模式下运行与编译为 JS 时,这些通常是不同的。

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

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

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

那么,当您在 a中列出任何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 实例没有用于跟踪新创建对象的字段,而是具有它们使用的静态成员——实际上是单例。这意味着一旦您调用了一次方法,它返回的实例将与您下次调用它时创建的实例相同。两个具有相同内容的不同 ClientBundles 当然会保留对象的两个不同副本,但是创建 ClientBundle 多少次并不重要——它的内部结构总是相同的。

还要别的吗?

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

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

现在,如果两个接口描述了相同的方法,您可能会遇到问题,但如果不是,这可以在生成精灵图像时提供优势。每个人ClientBundle在准备使用它们时都会使用自己的图像池 - 如果你有一个ClientBundlewithin a ClientBundle,它们将不会一起工作以将图像分割成更大的部分。要做到这一点,您只需要制作一种ClientBundle类型。这在您的特定情况下可能无关紧要,但我认为这也值得一提。

于 2013-12-04T23:03:21.737 回答