3

i'm wondering if there's a way to build the gwt uibinder logic into an abstract parent class so that i don't have to repeat the code in every class i want to bind.

for example, i'd like to be able to do something like this:

public abstract class BasePanel<Panel extends BasePanel> extends Composite {
    interface Binder<BinderPanel extends BasePanel> extends UiBinder<Widget, BinderPanel> { }
    private static final Binder binder = GWT.create(Binder<Panel>.class);

    public BasePanel() {
        initWidget(binder.createAndBindUi(this));
        init();
    }
}

basically this would allow any child classes to do something like this:

public MyPanel extends BasePanel<MyPanel> {
    //my code here
}

the default constructor would take care of all the code to bind MyPanel to MyPanel.ui.xml.

basically i want to be lazy and only have to build the interface and the binder once so that it's done in a common way. thoughts?

thanks in advance.

jctierney
  • 31
  • 1
  • 2

1 Answers1

6

Proper way to do abstract UI binder classes is to define a super class that will contain logic that is common to all subclass widgets. This class can have fields marked as @UiField, event handlers and anything else that goes into the UI binder class. And child classes actually have UI binder instantiation logic. So something like this:

public abstract BaseWidget extends Composite {
  @UiField TextBox textBoxCommon1;
  @UiField TextBox textBoxCommon2;

  @UiHandler("textBoxCommon1")
  void onTextBoxCommon1Changed( ValueChangeEvent<String> event ) {
    //...
  }

  @UiHandler("textBoxCommon2")
  void onTextBoxCommon2Changed( ValueChangeEvent<String> event ) {
    //...
  }
}

public class SomeWidget extends BaseWidget {
  interface SomeWidgetUiBinder extends UiBinder<Widget,SomeWidget> {}

  private static SomeWidgetUiBinder uiBinder = GWT.create(SomeWidgetUiBinder.class);

  @UiField Button someWidgetButton;

  public SomeWidget() {
    initWidget(uiBinder.createAndBindUi(this));
  }

  @UiHandler("someWidgetButton")
  void onButtonClicked(ClickEvent e) {
    Window.alert(textBoxCommon1.getValue());
  }
}
Strelok
  • 50,229
  • 9
  • 102
  • 115
  • If you want to avoid duplicate ui.xml code as well, you should still take this route. Put the would-be-duplicate layout code in a completely separate widget, though. This separate widget should implement `HasWidgets`, and then you can use it in all of your various subclass.ui.xml files. – Riley Lark Dec 08 '11 at 04:42
  • i've done both suggestions (common fields in the base widget and reducing ui.xml). i was really just wondering if the binder calls could be abstracted as well. it sounds like @strelock you're saying that it can't correct? – jctierney Dec 08 '11 at 14:25