Gwt ClientBundle for multiple";主题;

Gwt ClientBundle for multiple";主题;,gwt,uibinder,clientbundle,Gwt,Uibinder,Clientbundle,我们有一个web应用程序,每个主要客户机都需要不同的主题。最初的开发人员通过查看javascript中的URL并添加样式表来覆盖默认主题来实现这一点 其中一个问题是网站的默认外观会持续几秒钟,然后突然切换到正确的主题。另一个原因是它似乎浪费了很多带宽/时间 我目前的想法是使用默认的外观创建一个“默认”,扩展该接口,并使用各种注释(如@imageresource)和指向不同位置的客户机图像覆盖每个条目(根据需要) 有人有过这样做的经验吗?我提到的一个问题是不能使用uibinder样式的标记,因为它

我们有一个web应用程序,每个主要客户机都需要不同的主题。最初的开发人员通过查看javascript中的URL并添加样式表来覆盖默认主题来实现这一点

其中一个问题是网站的默认外观会持续几秒钟,然后突然切换到正确的主题。另一个原因是它似乎浪费了很多带宽/时间

我目前的想法是使用默认的外观创建一个“默认”,扩展该接口,并使用各种注释(如@imageresource)和指向不同位置的客户机图像覆盖每个条目(根据需要)

有人有过这样做的经验吗?我提到的一个问题是不能使用uibinder样式的标记,因为它们静态地指向特定的资源包


有什么想法吗?

凌驾于捆绑包之上

是的,你可以

我用ClientBundles做了覆盖,效果很好。您必须做的一件事就是继承属性的类型。举例来说:

BigBundle {
  Nestedundle otherBundle();
  ImageResource otherImage();
  Styles css();
}
然后你必须以这种方式继承:

OtherBigBundle extends BigBundle {
  OtherNestedBundle otherBundle(); // if you want to change it
  ImageResource otherImage(); // of you want to change it
  OtherStyles css(); // of you want to change it
}
OtherNestedBundle扩展NestedBundle
OtherStyles扩展样式

至少使用css:如果声明属性不使用子接口,它们将为相同的css类名生成样式,并且所有样式都将混合。所以用子接口声明覆盖的样式:)

柔性UIBinder

如果使用
UiField(provided=true)
annotation,则可以从捆绑包外部设置要使用的内容。通过这种方式,您首先设置bundle,然后调用uibindler。它将使用资源字段,假设它已经创建

延迟绑定

您可以使用GWT.runAsync加载正确的包

一些例子

ui.xml

<ui:with field='res' type='your.package.TheBundle'/>
一些包接口

interface TheBundle extends ClientBundle {
  @ImageResource("default.png")
  ImageResource image1();

  @Source("default.css")
  TheCss css();
}

interface Theme1Bundle extends TheBundle {
  @ImageResource("one.png")
  ImageResource image1(); // type: imageresource is ok

  @Source("one.css")
  OneCss css(); // type: OneCss => use other compiled css class-names

  interface OneCss extends TheCss { // inner-interface, just for fun
     // don't need to declare each String method
  }
}
如果你不重写某件事,那没关系

捆绑工厂的选项

1) 完全

if (...) {
  return GWT.create(TheBundle.class);
} else if (...) {
  return GWT.create(Theme1Bundle.class);
}
2) runAsync(只需加载所需的部分…但在执行初始部分之后)

3) 使用延迟绑定和生成器在编译时基于带注释的bundle(如
@ThemeBundle(“one”)

这个例子来自现实世界。我使用DynamicCentryPointWidgetFactory(简称DEPWidgetFactory)基于标识符字符串创建小部件。每个小部件都是一个应用程序屏幕,每个主菜单项都有它必须创建的widgetName

在您的情况下,id将是要创建的主题

重要提示:如果使用runAsync,则不能在创建UI之前创建resourcebundle,就像之前的示例代码中那样。您必须请求主题,当它准备好时(在回调中),将其传递给您的小部件构造函数,您的小部件可以将其分配给其字段

工厂界面:

public interface DynamicEntryPointWidgetFactory
{
   public void buildWidget(String widgetName, AsyncCallback<Widget> callback);
}
模块配置:

它说:工厂的实现将使用这个类生成(另一个选项是使用replace with,但在我们的例子中,我们没有为每个区域设置或浏览器预定义的选项,而是一些更动态的选项)


发电机:

public class DynamicEntryPointFactoryGenerator extends Generator {
    @Override
    public String generate(TreeLogger logger, GeneratorContext context,
            String typeName) throws UnableToCompleteException {
        PrintWriter pw = context.tryCreate(logger,
                "x.services.gwt.client.entrypoint",
                "DynamicEntryPointWidgetFactoryImpl");

        if (pw != null) {
            // write package, imports, whatever
            pw.append("package x.services.gwt.client.entrypoint;");
            pw.append("import x.services.gwt.client.entrypoint.DynamicEntryPointWidgetFactory;");
            pw.append("import com.google.gwt.core.client.GWT;");
            pw.append("import com.google.gwt.core.client.RunAsyncCallback;");
            pw.append("import com.google.gwt.user.client.rpc.AsyncCallback;");
            pw.append("import com.google.gwt.user.client.ui.Widget;");

            // the class
            pw.append("public class DynamicEntryPointWidgetFactoryImpl implements DynamicEntryPointWidgetFactory {");

            // buildWidget method
            pw.append("   public void buildWidget(String widgetName, final AsyncCallback<Widget> callback) {");

            // iterates over all the classes to find those with EntryPointWidget annotation
            TypeOracle oracle = context.getTypeOracle();
            JPackage[] packages = oracle.getPackages();
            for (JPackage pack : packages) 
            {
                JClassType[] classes = pack.getTypes();
                for (JClassType classtype : classes) 
                {
                    EntryPointWidget annotation = classtype.getAnnotation(EntryPointWidget.class);
                    if (annotation != null) 
                    {
                        String fullName = classtype.getQualifiedSourceName();
                        logger.log(TreeLogger.INFO, "Entry-point widget found: " + fullName);

                        pw.append("if (\"" + annotation.value() + "\".equals(widgetName)) {");
                        pw.append("   GWT.runAsync(" + fullName + ".class, new RunAsyncCallback() {");
                        pw.append("      public void onFailure(Throwable t) {");
                        pw.append("         callback.onFailure(t);");
                        pw.append("      }");
                        pw.append("      public void onSuccess() {");
                        pw.append("         callback.onSuccess(new " + fullName + "());");
                        pw.append("      }");
                        pw.append("   });");
                        pw.append("   return;");
                        pw.append("}");
                    }
                }
            }
            pw.append("callback.onFailure(new IllegalArgumentException(\"Widget '\" + widgetName + \"' not recognized.\"));");

            pw.append("   }");
            pw.append("}");

            context.commit(logger, pw);         
        }

        // return the name of the generated class
        return "x.services.gwt.client.entrypoint.DynamicEntryPointWidgetFactoryImpl";
    }
公共类DynamicCentryPointFactoryGenerator扩展生成器{
@凌驾
公共字符串生成(TreeLogger、GeneratorContext上下文、,
字符串类型名)引发UnableToCompleteException{
PrintWriter pw=context.tryCreate(记录器,
“x.services.gwt.client.entrypoint”,
“DynamicCentryPointWidgetFactoryImpl”);
如果(pw!=null){
//写包,导入,等等
append(“package x.services.gwt.client.entrypoint;”;
append(“import x.services.gwt.client.entrypoint.DynamicEntryPointWidgetFactory;”;
append(“import com.google.gwt.core.client.gwt;”);
append(“import com.google.gwt.core.client.RunAsyncCallback;”);
append(“import com.google.gwt.user.client.rpc.AsyncCallback;”);
append(“import com.google.gwt.user.client.ui.Widget;”;
//班级
append(“公共类DynamicEntryPointWidgetFactoryImpl实现DynamicEntryPointWidgetFactory{”);
//buildWidget方法
append(“publicvoidbuildwidget(字符串widgetName,finalasyncCallback){”);
//迭代所有类以查找具有EntryPointWidget注释的类
TypeOracleOracle=context.getTypeOracle();
JPackage[]packages=oracle.getPackages();
用于(JPackage-pack:packages)
{
JClassType[]classes=pack.getTypes();
for(JClassType类类型:类)
{
EntryPointWidget annotation=classtype.getAnnotation(EntryPointWidget.class);
if(注释!=null)
{
字符串fullName=classtype.getQualifiedSourceName();
logger.log(TreeLogger.INFO,“找到入口点小部件:“+fullName”);
append(“if(\”“+annotation.value()+“\”.equals(widgetName)){”);
append(“GWT.runAsync(“+fullName+”.class,新的RunAsyncCallback(){”);
附加(“公共失效无效(可丢弃的t){”);
append(“callback.onFailure(t);”;
附加(“}”);
append(“public void onSuccess(){”);
append(“callback.onSuccess(new“+fullName+”());”;
附加(“}”);
附加(“}”);”;
附加(“返回;”;
附加(“}”);
}
}
}
public interface DynamicEntryPointWidgetFactory
{
   public void buildWidget(String widgetName, AsyncCallback<Widget> callback);
}
@Target(ElementType.TYPE)
public @interface EntryPointWidget 
{
    /**
     * The name wich will be used to identify this widget.
     */
    String value();
}
<generate-with class="com.dia.nexdia.services.gwt.rebind.entrypoint.DynamicEntryPointFactoryGenerator">
  <when-type-assignable class="com.dia.nexdia.services.gwt.client.entrypoint.DynamicEntryPointWidgetFactory" />
</generate-with>
public class DynamicEntryPointFactoryGenerator extends Generator {
    @Override
    public String generate(TreeLogger logger, GeneratorContext context,
            String typeName) throws UnableToCompleteException {
        PrintWriter pw = context.tryCreate(logger,
                "x.services.gwt.client.entrypoint",
                "DynamicEntryPointWidgetFactoryImpl");

        if (pw != null) {
            // write package, imports, whatever
            pw.append("package x.services.gwt.client.entrypoint;");
            pw.append("import x.services.gwt.client.entrypoint.DynamicEntryPointWidgetFactory;");
            pw.append("import com.google.gwt.core.client.GWT;");
            pw.append("import com.google.gwt.core.client.RunAsyncCallback;");
            pw.append("import com.google.gwt.user.client.rpc.AsyncCallback;");
            pw.append("import com.google.gwt.user.client.ui.Widget;");

            // the class
            pw.append("public class DynamicEntryPointWidgetFactoryImpl implements DynamicEntryPointWidgetFactory {");

            // buildWidget method
            pw.append("   public void buildWidget(String widgetName, final AsyncCallback<Widget> callback) {");

            // iterates over all the classes to find those with EntryPointWidget annotation
            TypeOracle oracle = context.getTypeOracle();
            JPackage[] packages = oracle.getPackages();
            for (JPackage pack : packages) 
            {
                JClassType[] classes = pack.getTypes();
                for (JClassType classtype : classes) 
                {
                    EntryPointWidget annotation = classtype.getAnnotation(EntryPointWidget.class);
                    if (annotation != null) 
                    {
                        String fullName = classtype.getQualifiedSourceName();
                        logger.log(TreeLogger.INFO, "Entry-point widget found: " + fullName);

                        pw.append("if (\"" + annotation.value() + "\".equals(widgetName)) {");
                        pw.append("   GWT.runAsync(" + fullName + ".class, new RunAsyncCallback() {");
                        pw.append("      public void onFailure(Throwable t) {");
                        pw.append("         callback.onFailure(t);");
                        pw.append("      }");
                        pw.append("      public void onSuccess() {");
                        pw.append("         callback.onSuccess(new " + fullName + "());");
                        pw.append("      }");
                        pw.append("   });");
                        pw.append("   return;");
                        pw.append("}");
                    }
                }
            }
            pw.append("callback.onFailure(new IllegalArgumentException(\"Widget '\" + widgetName + \"' not recognized.\"));");

            pw.append("   }");
            pw.append("}");

            context.commit(logger, pw);         
        }

        // return the name of the generated class
        return "x.services.gwt.client.entrypoint.DynamicEntryPointWidgetFactoryImpl";
    }