UiBinder

UiBinder以前、GWTアプリケーションで画面レイアウトを作るにはHTML外では全てJavaコードで書く必要があった。

  • コードで書くレイアウト
  private VerticalPanel mainPanel = new VerticalPanel();
  private FlexTable stocksFlexTable = new FlexTable();
  private HorizontalPanel addPanel = new HorizontalPanel();
  private TextBox newSymbolTextBox = new TextBox();
  private Button addStockButton = new Button("Add");
  private Label lastUpdatedLabel = new Label();
  
  public void onModuleLoad() {
    :
    addPanel.add(newSymbolTextBox);
    addPanel.add(addStockButton);

    mainPanel.add(stocksFlexTable);
    mainPanel.add(addPanel);
    mainPanel.add(lastUpdatedLabel);

    RootPanel.get("stockList").add(mainPanel);
  }

この方法はJFC/Swing等と同様「手続き型」と呼ばれる方法であり、どのようにUIが構成されているか順を追って分かりやすい反面、コードとUIが同居しているためデザインと処理を分離するのが困難になっている。また、この方法ではWISYWIGで画面をデザインする際にコードとの同期を取る必要があるため、GUIデザイナとの連携がどうしても難しいものとなる。※1

開発時に画面を出来るだけWISYWIGでプレビューできるように、コードとレイアウトを分離するために考え出されたのが「宣言型」と呼ばれる方法であり、画面のレイアウトや部品の配置をXML等のマークアップで実現するのが最近の主流になっている。この方法ではデザイナとコードの同期が必要無く自由度が高くなる。またASP.NETのコードビハインドのようにコンテキストを共有できるものもある※2

UiBinderはそれまで手続き型でしか出来なかった画面のレイアウトを宣言型で可能とし、更にASP.NET コードビハインドのようにレイアウトとコードの連携を可能にした画期的な機能である。GWTではversion 2.0からUiBinderをサポートしている。

UiBinderの狙い

    • 生産性と保守性の向上
    • Javaコードよりも分かりやすいXML, HTML、CSSとUIデザイナの連携
    • HTMLで作ったモックからGWTへの段階的な移行を提供
    • UIとプログラム(Javaクラス)との分離を促進
    • コンパイル時にJavaコードとUiBinder XML相互のリファレンスチェックを提供
    • GWT-i18n機構を利用した国際化サポート
    • ウィジェットやパネルの使用を促進することでブラウザリソースを効果的に利用
  • UiBinderで定義したレイアウト
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:a="urn:import:net.kazzz.client"
>
 <ui:style></ui:style>
 <g:HTMLPanel styleName="AddressInfo">
   <g:Grid ui:field="pnlAddressInfo" >
     <g:row>
       <g:customCell><g:Label ui:field="lblFullName" text="氏名"/></g:customCell>
       <g:customCell><g:TextBox ui:field="txtFullName" visibleLength="20"/></g:customCell>
     </g:row>
     <g:row>
       <g:customCell><g:Label ui:field="lblAddress" text="住所"/></g:customCell>
       <g:customCell><g:TextBox ui:field="txtAddress" visibleLength="60"/></g:customCell>
     </g:row>
     <g:row>
       <g:customCell><g:Label ui:field="lblEmail" text="e-mail"/></g:customCell>
       <g:customCell><g:TextBox ui:field="txtEmail" visibleLength="20"/></g:customCell>
     </g:row>
     <g:row>
       <g:customCell><g:Label ui:field="lblMarried" text="既婚"/></g:customCell>
       <g:customCell><g:CheckBox ui:field="chkMarried" checked="false"/></g:customCell>
     </g:row>
     <g:row>
       <g:customCell><g:Label ui:field="lblGender" text="性別"/></g:customCell>
       <g:customCell>
         <g:HorizontalPanel>
           <g:RadioButton ui:field="rdoMale" name="gender" text="男"/>
           <g:RadioButton ui:field="rdoFemale" name="gender" text="女"/>
         </g:HorizontalPanel>
       </g:customCell>
     </g:row>
   </g:Grid>
 </g:HTMLPanel>
</ui:UiBinder> 

実際に使ってみれば分かるが、UiBinderはこのようにXMLで宣言的にレイアウトを作ることが出来、とても便利である。

日本では情報が少ないせいか、一部を除いてあまり利用が進まないGWTだが、非常に優れた面があり個人的にはこれからどんどん使っていきたいと考えている。

GWTのUiBinderには他にも有用な機能が幾つかあるが、それは次回以降に紹介したいと思う。

※1 古くはJavaJBuilderや最近ではNetBeans等のように手続き型のGUIであってもGUIデザイナで画面をデザインできる物もあるが、拡張ライブラリィが必要だったり独自の実装が必要だったりとどうしても複雑になってしまう。

※2 XAMLAndroidもこの方式である