Monday, February 28, 2011

UiBinder Check List

Gloassary:
  • UI template: The ui.xml file used for declaring the client visuals.
  • UI template bean: The java source that is associated with a ui.xml file.
  • UI-set: The two files that constitute the template-bean pair.
    Example of a UI-set: abc.ui.xml <=> abc.java.
  • External bean: A java class other than the template bean being referenced within the template.

Avoid having more than one entry point in a module.
The client visuals of all entry points within a module will be overlaid together.


A module should not inherit an entry point.
The client visuals of an inherited entry point will be overlaid onto the current entry point's.

@UiFactory directive
is for declaring a factory method which would be used to generate the xml declaration of a widget in the ui template. This is useful in customising gwt widgets if all instances of a widget in a UI-set.

The name of the factory method is inconsequential and therefore there should be only one UiFactory method for each type.

For example, in the following, methodNameRegardless() wlll be used to generate all instances of DialogBox declared in the ui template.

abc.java Bean:
@UiFactory DialogBox methodNameRegardless(){
  ....
}

abc.ui.xml template:
</g:dialogbox ... >


ui:with for referencing an external bean
The ui:with declaration is used for directly instantiating and accessing a java class to be used as a bean.

com.syntercourse.maine.client.MaineMenu.ui.xml:
<ui:with type="com.syntercourse.menu.Commands" field="cmds"/>

So that henceforth, any visible method in com.syntercourse.menu.Commands class would be addressable. For example,

<g:MenuItem text="login"
command="{cmds.getLoginCmd}"/>

com.syntercourse.menu.Commands.java:
Command getLoginCmd(){
  return new  Command() {

    public void execute() {
      userService.createLoginURL(loggedInUrl, googinRPCCallback);
    }
}


ui:with for referencing the ui template bean
ui:with will instantiate the bean declared in the type attribute. When referencing the ui template bean, the ui template should not be reinstantiated (in most cases, reinstantiating its own bean would end up in an endless loop). In order to prevent a ui:with from instantiating a bean (the template bean or external bean), the template bean should declare a @UiField(provided=true) for that ui:with declaration.

com.syntercourse.maine.client.MaineMenu.ui.xml:
<ui:with type="com.syntercourse.maine.client.MaineMenu" field="bean"/>

So that henceforth, any visible method in the template bean would be addressable. For example,

<g:MenuItem text="login"
command="{bean.getLoginCmd}"/>

com.syntercourse.maine.client.MaineMenu.java:
public class MaineMenu
extends Composite{
  private final UserServiceWrapperAsync userService =
    GWT.create(UserServiceWrapper.class);

  private static final Binder binder =
    GWT.create(Binder.class);
  interface Binder extends UiBinder {}
  public MaineMenu() {
    this.bean = this; /*Important, otherwise nullpointerexception*/
    initWidget(binder.createAndBindUi(this));
  }

  @UiField(provided=true) MaineMenu bean;

  Command getLoginCmd(){
    return new Command() {
      public void execute() {
        userService.createLoginURL(loggedInUrl, loginRPCCallback);
      }
    }
  }
}


UiFactory for referencing members in the ui template bean
The @UiFactory combination can also be used to access the members of a template bean.

com.syntercourse.maine.client.MaineMenu.ui.xml:
<g:MenuItem text="login" command="{bean}"/>

com.syntercourse.maine.client.MaineMenu.java:
public class MaineMenu
extends Composite{
  private final UserServiceWrapperAsync userService =
    GWT.create(UserServiceWrapper.class);

  private static final Binder binder =
    GWT.create(Binder.class);
  interface Binder extends UiBinder {}
  public MaineMenu() {
    initWidget(binder.createAndBindUi(this));
  }
  @UiFactory Login bean(){
    return this;
  }
  class Login implements Command(){
    public void execute() {
      userService.createLoginURL(
        loggedInUrl, loginRPCCallback);
    }  
  }
}


UiFactory for referencing members in external bean
The @UiFactory combination can also be used to access the members of a template bean.

com.syntercourse.maine.client.MaineMenu.ui.xml:
<g:MenuItem text="login" command="{cmdfactory.loginCmd}"/>

com.syntercourse.maine.client.MaineMenu.java:
public class MaineMenu
extends Composite{
  private final UserServiceWrapperAsync userService =
    GWT.create(UserServiceWrapper.class);

  private static final Binder binder =
    GWT.create(Binder.class);
  interface Binder extends UiBinder {}
  public MaineMenu() {
    initWidget(binder.createAndBindUi(this));
  }
  @UiFactory CommandFactory cmdfactory(){
    return new CommandFactory();
  }
  class Login implements Command(){
    public void execute() {
      userService.createLoginURL(
        loggedInUrl, loginRPCCallback);
    }  
  }
}


com.syntercourse.maine.client.CommandFactory.java:
public class CommandFactory{
Command loginCmd = new Command(){
    public void execute() {
      userService.createLoginURL(
        loggedInUrl, loginRPCCallback);
    }  
  }
}