オーバーライドされたバンドル
はい、できます。
私は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 extends NestedBundle
とOtherStyles extends Styles
少なくともcssの場合:プロパティが子インターフェイスを使用しないと宣言されている場合、それらは同じCSSクラス名のスタイルを生成し、すべてが混在します。したがって、子インターフェイスでオーバーライドされたスタイルを宣言します:)
柔軟なUIBinders
UiField(provided=true)
アノテーションを使用する場合は、バンドルの外部から使用するように設定できます。このようにして、最初にバンドルを設定してから、uibindlerを呼び出します。すでに作成されていると仮定して、リソースフィールドを使用します。
遅延バインディング
GWT.runAsyncを使用して、正しいバンドルだけをロードできます。
いくつかの例
ui.xml
<ui:with field='res' type='your.package.TheBundle'/>
対応するクラス
@UiField(provided=true) TheBundle bundle;
private void createTheThing() {
this.bundle = factory.createBundle();
MyUiBindler binder = GWT.create(MyUiBindler.class);
this.panel = binder.createAndBindUi(this);
...
}
一部のバンドルインターフェイス
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(必要な部分をロードするだけですが、最初の部分が実行された後)
if (...) {
GWT.runAsync(new RunAsyncCallback() {
public void onSuccess() {
return GWT.create(TheBundle.class);
}
// please program the onFailure method
});
} else if (...) {
GWT.runAsync(new RunAsyncCallback() {
public void onSuccess() {
return GWT.create(Theme1Bundle.class);
}
// please program the onFailure method
});
}
3)次のような注釈付きバンドルに基づいてコンパイル時にファクトリを自動生成するために遅延バインディングとジェネレータを使用します@ThemeBundle("one")
この例は実世界のものです。識別子文字列に基づいてウィジェットを作成するために、DynamicEntryPointWidgetFactory(略してDEPWidgetFactory)を使用します。各ウィジェットはアプリケーション画面であり、各メインメニューには作成する必要のあるwidgetNameがあります。
あなたの場合、IDが作成するテーマになります。
重要: runAsyncを使用する場合、前のサンプルコードのように、UIを作成する直前にリソースバンドルを作成することはできません。テーマを要求する必要があり、準備ができたら(コールバックで)ウィジェットコンストラクターに渡します。ウィジェットはそれをフィールドに割り当てることができます。
ファクトリインターフェイス:
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();
}
モジュール構成:
Factoryの実装はこのクラスで生成されます(他のオプションはreplace-withを使用することですが、この場合、ロケールまたはブラウザーごとに事前定義されたオプションはありませんが、より動的なものがあります)。
<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";
}