Revision: 7305
Author: [email protected]
Date: Sun Dec 13 13:50:48 2009
Log: Edited wiki page through web user interface.
http://code.google.com/p/google-web-toolkit/source/detail?r=7305

Modified:
  /wiki/UiBinder.wiki

=======================================
--- /wiki/UiBinder.wiki Tue Dec  8 05:58:37 2009
+++ /wiki/UiBinder.wiki Sun Dec 13 13:50:48 2009
@@ -2,551 +2,4 @@

  = GWT UiBinder Use Cases =

-Ray Ryan
-
-This document provides various use cases for the use of the UiBinder, a  
service to generate Widget and DOM structures from XML markup, to be  
introduced with GWT 2.0. Unless otherwise noted, everything described here  
has been implemented.
-
-The samples here ignore binder's localization features. See UiBinderI18n.
-
-= Quick start =
-
-If just want to jump right in, take a peak at  
[http://code.google.com/p/google-web-toolkit/source/detail?r=6192 this  
patch]. It includes
-the work to change the venerable Mail sample to use UiBinder.
-
-= Background =
-
-There are problems with the declarative ui template service as it was  
[DeclarativeUi originally proposed]
-
-  * A template-based UI must be instantiated via GWT.create(), causing an  
implementation detail to be visible as public api
-  * Within a template, only widgets with a zero arg constructor can be used
-  * CssResource and other ImmutableResourceBundle variants cannot be used
-  * Template xml files are found by magical name matching conventions, and  
applying more than one xml template to a class is impossible
-
-In addressing these issues, we have talked about encouraging a proxy style  
of use (basically, use Composite to wrap whatever widget gets  
GWT.create()'d), but dislike the extra object creation implied. We also  
hope for a system that can choose to use innerHTML, cloning, or DOM  
assembly as makes sense per browser type. These shortcomings could be  
addressed by a combination of developer discipline (yuck) and perhaps the  
builder pattern, but we still found ourselves faced with the likelihood of  
hurried developers wrapping an unneeded, generated object.
-
-Emily hit upon the idea of the Configurator (here rechristened UiBinder).  
It’s like a factory, but responsible for filling in the fields of a Widget  
(or other object) that someone else instantiates, rather than instantiating  
one itself. This seems to offer all the benefits of a builder, with no  
concerns of extra object creation, and as a nice side effect avoids a lot  
of boilerplate. This document illustrates its application in various use  
cases.
-
-{{{
-/**
- * Interface implemented by classes that generate DOM or Widget structures  
from
- * ui.xml template files, and which inject portions of the generated UI  
into the
- * fields of an owner.
- * <p>
- * The generated UiBinder implementation will be based on an xml file  
resource
- * in the same package as the owner class, with the same name and  
a "ui.xml"
- * suffix. For example, a UI owned by class {...@code bar.baz.Foo} will be  
sought
- * in {...@code /bar/baz/Foo.ui.xml}. (To use a different template file, put  
the
- * {...@link UiTemplate} annotation on your UiBinder interface declaration to  
point
- * the code generator at it.)
- *
- * @param <U> The type of the root object of the generated UI, typically a
- *          subclass of {...@link com.google.gwt.dom.client.Element} or
- *          {...@link com.google.gwt.user.client.ui.UIObject}
- * @param <O> The type of the object that will own the generated UI
- */
-public interface UiBinder<U, O> {
-
-  /**
-   * Creates and returns the root object of the UI, and fills any fields  
of owner
-   * tagged with {...@link UiField}.
-   *
-   * @param owner the object whose {...@literal @}UiField needs will be filled
-   */
-  U createAndBindUi(O owner);
-}
-}}}
-
-= Hello World =
-
-Make a simple generated UI, with a named element, and without widgets.
-
-{{{
-<!-- HelloWorld.ui.xml -->
-
-<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
-  <div>
-    Hello, <span ui:field='nameSpan'/>.
-  </div>
-</ui:UiBinder>
-}}}
-
-{{{
-public class HelloWorld extends UIObject { // Could extend Widget instead
-
-  interface MyUiBinder extends UiBinder<DivElement, HelloWorld> {}
-  private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
-
-  @UiField SpanElement nameSpan;
-
-  public HelloWorld(String name) {
-    // call to createAndBindUi sets this.nameSpan
-    setElement(uiBinder.createAndBindUi(this));
-    nameSpan.setInnerText(name);
-  }
-}
-
-// Use:
-
-HelloWorld helloWorld = new HelloWorld("World");
-Document.get().getBody().appendChild(helloWorld.getElement());
-}}}
-
-= Hello Composite World =
-
-Make a simple widget-based UI
-
-{{{
-<!-- HelloWidgetWorld.ui.xml -->
-
-<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
-    xmlns:g='urn:import:com.google.gwt.user.client.ui'>
-  <g:HTMLPanel>
-    Hello, <g:ListBox ui:field='listBox'/>.
-  </g:HTMLPanel>
-</ui:UiBinder>
-}}}
-
-{{{
-public class HelloWidgetWorld extends Composite {
-
-  interface MyUiBinder extends UiBinder<Widget, HelloWidgetWorld> {}
-  private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
-
-  @UiField ListBox listBox;
-
-  public HelloWidgetWorld(String... names) {
-    // sets listBox
-    initWidget(uiBinder.createAndBindUi(this));
-    for (String name : names) { listBox.addItem(name); }
-  }
-}
-
-// Use:
-
-HelloWidgetWorld helloWorld =
-  new HelloWidgetWorld("able", "baker", "charlie");
-}}}
-
-= HTML entities =
-
-XML doesn't understand entities like {{{&nbsp;}}}. Templates that needs  
such characters
-have to define them. As a convenience, we provide a set of definitions  
that you can
-import by setting your DOCTYPE appropriately:
-
-{{{
-<!DOCTYPE ui:UiBinder  
SYSTEM "http://google-web-toolkit.googlecode.com/files/xhtml.ent";>
-}}}
-
-Note that the GWT compiler won't actually visit this url to fetch the file.
-There is a copy baked into it is used when that url is seen. However, your
-IDE may will fetch it.
-
-= Hello Stylish World =
-
-With the <ui:style> element, you can define the CSS for your UI right
-where you need it.
-
-{{{
-<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
-  <ui:style>
-    .pretty { background-color: Skyblue; }
-  </ui:style>
-
-  <div class='{style.pretty}'>
-    Hello, <span ui:field='nameSpan'/>.
-  </div>
-</ui:UiBinder>
-}}}
-
-A CssResource interface is generated for you, along with a ClientBundle.  
This means that the compiler
-will warn you if you misspell the class name when you try to use it (e.g.  
{style.prettty}). Also,
-your css class name will be obfuscated, and so protected from collision  
with like classnames
-in other css blocks--no more global CSS namespace!
-
-In fact, you can take advantage of this within a single template:
-
-{{{
-<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
-  <ui:style>
-    .pretty { background-color: Skyblue; }
-  </ui:style>
-  <ui:style field='otherStyle'>
-    .pretty { background-color: Orange; }
-  </ui:style>
-
-  <div class='{style.pretty}'>
-    Hello, <span class='{otherStyle.pretty}' ui:field='nameSpan'/>.
-  </div>
-</ui:UiBinder>
-}}}
-
-Finally, you don't have to have your CSS inside your ui.xml file.
-Most real world projects will probably keep their CSS in a separate file:
-
-{{{
-<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
-  <ui:style src="MyUi.css" />
-  <ui:style field='otherStyle' src="MyUiOtherStyle.css">
-
-  <div class='{style.pretty}'>
-    Hello, <span class='{otherStyle.pretty}' ui:field='nameSpan'/>.
-  </div>
-</ui:UiBinder>
-}}}
-
-
-= Programatic access to inline Styles =
-
-(*type='' doesn't allow for multiple interfaces. Needs thinking*)
-
-{{{
-  <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
-    <ui:style type='com.my.app.MyFoo.MyStyle'>
-      .redBox { background-color:pink; border: 1px solid red; }
-      .enabled { color:black; }
-      .disabled { color:gray; }
-    </ui:style>
-
-    <div class='{style.redBox} {style.enabled}'>I'm a box. And I'm  
red.</div>
-  </ui:UiBinder>
-}}}
-
-{{{
-  public class MyFoo extends Widget {
-    interface MyStyle extends CssResource {
-      String enabled();
-      String disabled();
-    }
-
-    @UiField MyStyle style;
-
-    /* ... */
-
-    void setEnabled(boolean enabled) {
-      getElement().addStyle(enabled ? : style.enabled() :  
style.disabled());
-      getElement().removeStyle(enabled ? : style.disabled() :  
style.enabled());
-    }
-  }
-}}}
-
-=Simple binding of event handlers=
-
-(* Should the value argument ("button") should be optional? If so the  
handler should get all clickEvents
-if it is not provided. But what does "all" mean, exactly? For every named  
field? *)
-
-(* Cannot yet bind to non-widgets *)
-
-{{{
-  public class MyFoo extends Widget {
-
-  @UiField Button button;
-
-  /* ... */
-
-  @UiHandler("button")
-  void onClick(ClickEvent e) {
-    Window.alert("Hello, AJAX");
-  }
-}}}
-
-=Using an external resource with a UiBinder=
-
-{{{
-<!-- LogoNamePanel.ui.xml -->
-<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
-    xmlns:g='urn:import:com.google.gwt.user.client.ui'>
-
-  <ui:with field='res' type='com.my.app.widgets.logoname.Resources'/>
-
-  <g:HTMLPanel>
-
-    <g:Image resource='{res.logoImage}'>
-
-    <div class='{res.style.mainBlock}'>
-      <div class='{res.style.userPictureSprite}' />
-      <div>
-        Well hello there
-        <span class='{res.style.nameSpan}' ui:field='userNameField'/>
-      </div>
-    </div>
-  </g:HTMLPanel>
-</ui:UiBinder>
-}}}
-
-{{{
-public class LogoNamePanel extends Composite {
-  interface MyUiBinder extend UiBinder<Widget, LogoNamePanel> {}
-  private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
-
-  @UiField SpanElement userNameField;
-
-  public LogoNamePanel() {
-    initWidget(uiBinder.createAndBindUi(this));
-  }
-
-  public void setUserName(String userName) {
-    userNameField.setInnerText(userName);
-  }
-}
-
-public interface Resources extends ClientBundle {
-  @Resource("Style.css")
-  Style style();
-
-  @Resource("Logo.jpg")
-  ImageResource logoImage();
-
-  public interface Style extends CssResource {
-    String mainBlock();
-    String nameSpan();
-    Sprite userPictureSprite();
-  }
-}
-}}}
-
-The with element declares a field holding an object whose methods can be  
called to fill
-in attribute values. If no public api is provided to set the "with"
-argument (as in this example), it must be instantiable by
-GWT.create().
-
-Note that there is no requirement that a ui:with resource implement
-the ClientBundle interface, this is just an example.
-
-=Share resource instances=
-
-Extends LogoNamePanel (from the example above) to allow the resource to be  
passed in.
-
-{{{
-public class LogoNamePanel extends Composite {
-  interface MyUiBinder extend UiBinder<Widget, LogoNamePanel> {}
-  private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
-
-  @UiField SpanElement nameSpan;
-  final Resources resources;
-
-  public LogoNamePanel(Resources resources) {
-    this.resources = resources;
-    initWidget(uiBinder.createAndBindUi(this));
-  }
-
-  public void setUserName(String userName) {
-    nameSpan.setInnerText(userName);
-  }
-
-  @UiFactory /* this method could be static */
-  public Resources getResources() {
-    return resources;
-  }
-}
-}}}
-
-This can be even more concise:
-
-{{{
-public class LogoNamePanel extends Composite {
-  interface MyUiBinder extend UiBinder<Widget, LogoNamePanel> {}
-  private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
-
-  @UiField SpanElement nameSpan;
-  @UiField(provided = true)
-  final Resources resources;
-
-  public LogoNamePanel(Resources resources) {
-    initWidget(uiBinder.createAndBindUi(this));
-    this.resources = resources;
-  }
-
-  public void setUserName(String userName) {
-    nameSpan.setInnerText(userName);
-  }
-}
-}}}
-
-
-=Using a widget that requires constructor args=
-
-You have an existing widget that needs constructor arguments.
-
-{{{
-public CricketScores(String... teamNames) {...}
-}}}
-
-You use it in a template.
-
-{{{
-<!-- UserDashboard.ui.xml -->
-<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
-    xmlns:g='urn:import:com.google.gwt.user.client.ui'
-    xmlns:my='urn:import:com.my.app.widgets' >
-
-  <g:HTMLPanel>
-    <my:WeatherReport ui:field='weather'/>
-    <my:Stocks ui:field='stocks'/>
-    <my:CricketScores ui:field='scores' />
-  </g:HTMLPanel>
-</ui:UiBinder>
-}}}
-
-{{{
-public class UserDashboard extends Composite {
-  interface MyUiBinder extends UiBinder<Widget, UserDashboard> {}
-  private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
-
-  public UserDashboard() {
-    initWidget(uiBinder.createAndBindUi(this));
-  }
-}
-}}}
-
-An error results: *(line numbers not yet implemented)*
-
-{{{
-
-UserDashboard.ui.xml:7:2 [ERROR] com.my.app.widgets.CricketScores
-has no default (zero args) constructor. You can define a
-...@uifactory annotated method on UserDashboard to create an instance;
-mark a CrickectScores field of UserDashboard with @UiField(provided=true)
-and put an instance there; or annotate a constructor of CricketScores with
-...@uiconstructor to allow its arguments to be provided by the template.
-
-}}}
-
-So you either make the @UiFactory method:
-
-{{{
-public class UserDashboard extends Composite {
-  interface MyUiBinder extends UiBinder<Widget, UserDashboard>;
-  private static final MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
-
-  private final String[] teamNames;
-
-  public UserDashboard(String... teamNames) {
-    this.teamNames = teamNames;
-    initWidget(uiBinder.createAndBindUi(this));
-  }
-
-  /** Used by MyUiBinder to instantiate CricketScores */
-  @UiFactory CricketScores makeCricketScores() { // method name is  
insignificant
-    return new CricketScores(teamNames);
-  }
-}
-}}}
-
-or perhaps:
-
-{{{
-public class UserDashboard extends Composite {
-  interface MyUiBinder extends UiBinder<Widget, UserDashboard>;
-  private static final MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
-
-  public UserDashboard() {
-    this.teamNames = teamNames;
-    initWidget(uiBinder.createAndBindUi(this));
-  }
-
-  /**
-   * Used by MyUiBinder to instantiate CricketScores.
-   * Arguments to be filled in the template
-   */
-  @UiFactory CricketScores makeCricketScores(String... teamNames) {
-    return new CricketScores(teamNames);
-  }
-}
-}}}
-
-{{{
-<!-- UserDashboard.ui.xml -->
-<g:HTMLPanel xmlns:ui='urn:ui:com.google.gwt.uibinder'
-  xmlns:g='urn:import:com.google.gwt.user.client.ui'
-  xmlns:my='urn:import:com.my.app.widgets' >
-
-  <my:WeatherReport ui:field='weather'/>
-  <my:Stocks ui:field='stocks'/>
-  <my:CricketScores ui:field='scores' teamNames='AUS, SAF, WA, QLD, VIC'/>
-</g:HTMLPanel>
-}}}
-
-or annotate the constructor:
-
-{{{
-public @UiConstructor CricketScores(String... teamNames) {...}
-}}}
-
-{{{
-<!-- UserDashboard.ui.xml -->
-<g:HTMLPanel xmlns:ui='urn:ui:com.google.gwt.uibinder'
-  xmlns:g='urn:import:com.google.gwt.user.client.ui'
-  xmlns:my='urn:import:com.my.app.widgets' >
-
-  <my:WeatherReport ui:field='weather'/>
-  <my:Stocks ui:field='stocks'/>
-  <my:CricketScores ui:field='scores' teamNames='AUS, SAF, WA, QLD, VIC'/>
-</g:HTMLPanel>
-}}}
-
-or fill in a field marked with @UiField(provided=true):
-
-{{{
-public class UserDashboard extends Composite {
-  interface MyUiBinder extends UiBinder<Widget, UserDashboard>;
-  private static final MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
-
-  @UiField(provided=true)
-  final CricketScores cricketScores; // cannot be private
-
-  public UserDashboard(CricketScores cricketScores) {
-    // DI fans take note!
-    this.cricketScores = cricketScores;
-    initWidget(uiBinder.createAndBindUi(this));
-  }
-}
-}}}
-
-=Apply different xml templates to the same widget=
-
-You're an  
[http://code.google.com/events/io/sessions/GoogleWebToolkitBestPractices.html  
MVP] developer. You have a nice view interface, and a templated Widget that  
implements it. How might you use several different xml templates for the  
same view?
-
-{{{
-public class FooPickerController {
-  public interface Display {
-    HasText getTitleField();
-    SourcesChangeEvents getPickerSelect();
-  }
-
-  public void setDisplay(FooPickerDisplay display) { ... }
-}
-
-public class FooPickerDisplay extends Composite
-    implements FooPickerController.Display {
-
-  @UiTemplate("RedFooPicker.ui.xml")
-  interface RedBinder extends UiBinder<Widget, FooPickerDisplay> {}
-  private static RedBinder redBinder = GWT.create(MyUiBinder.class);
-
-  @UiTemplate("BlueFooPicker.ui.xml")
-  interface BlueBinder extends UiBinder<Widget, FooPickerDisplay> {}
-  private static BlueBinder blueBinder = GWT.create(MyUiBinder.class);
-
-  @UiField HasText titleField;
-  @UiField SourcesChangeEvents pickerSelect;
-
-  public HasText getTitleField() {
-    return titleField;
-  }
-  public SourcesChangeEvents getPickerSelect() {
-    return pickerSelect;
-  }
-
-  protected FooPickerDisplay(UiBinder<Widget, FooPickerDisplay> binder) {
-    initWidget(binder.createAndBindUi(this));
-  }
-
-  public static FooPickerDisplay createRedPicker() {
-    return new FooPickerDisplay(redBinder);
-  }
-
-  public static FooPickerDisplay createBluePicker() {
-    return new FooPickerDisplay(blueBinder);
-  }
-}
-}}}
+This page has been moved to  
http://code.google.com/webtoolkit/doc/latest/DevGuideUiBinder.html

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to