GWT SyncProxy-0.1.1New!           Bean Properties Editor for JDeveloper 11gNew!. -->
  gwtXPDownloadsBlog

Understanding gwtXP

 

gwtXP Components

GwtXP interface

GwtXP Interface is used for code generation.

package com.gdevelop.gwtxp.client;
public interface GwtXP {
 /**
 * Get the DataBindingContext for this gwtXP, create a new one if needed.
 * @see org.eclipse.core.databinding.DataBindingContext
 * @return the DataBindingContext
 */
 public DataBindingContext getDataBindingContext();

 /**
 * Get the root UI object, create a new one if needed.
 * @return The root UI object declared in gwtXP file.
 */
 public UIObject getGUI();

 /**
 * Get the UI object by its name, <code>null</code> if not found.
 * @param name UI object name.
 * @return The UI object which is declared in gwtXP file.
 */
 public UIObject getUI(String name);
}

The module com.gdevelop.gwtxp.GwtXP.gwt.xml

This module defines GwtXPGenerator class for GwtXP interface.

<module>
  ...
  <generate-with class="com.gdevelop.gwtxp.rebind.GwtXPGenerator">
    <when-type-assignable class="com.gdevelop.gwtxp.client.GwtXP" />
  </generate-with>
  ...
</module>

As you may know, when you call GWT.create(GwtXP.class), GWT will create a new GwtXPGenerator instance and invoke its generate method.

The class GwtXPGenerator

GwtXPGenerator will scan for XML definition files in the project source path and generate Java code for these files, e.g transform elements in XML definition files to GWT widgets.

This transformation process is as below:

  • Parse and validate the XML definition file.
  • Iterate through every elements in this file, lookup a appropriated <code>Tag</code> class for that element.
  • Call Tag’s methods to generate code for the element.
  • The Tag in turn generate code for: widget declaration, widget instantiation, widget’s properties setup, data binding and handler registration.

Because gwtXP is open source, advanced readers can look at its source code for further details.

And your XML definition files

As described in above, GwtXPGenerator scans for XML definition files. You have to write these files to build up your UI.

gwtXP file structure

XML definition file is parsed and validated against gwtXP schema. The schema gwtXP.xsd file is included in the distribution. Snippets below outlines the important parts of gwtXP.xsd schema

Root element:

<xsd:complexType name="gwtxpType">
  <xsd:sequence>
  <xsd:element ref="widget" maxOccurs="1"/>
  </xsd:sequence>
  <xsd:attribute name="controllerClassName" type="xsd:string"/>
  </xsd:complexType>
<xsd:element name="gwtxp" type="gwtxpType"/>

UIObjectType and WidgetType define type UIObject and Widget

<xsd:complexType name="UIObjectType" abstract="true">
  <xsd:attribute name="height" type="xsd:string"/>
  <xsd:attribute name="styleName" type="xsd:string"/>
  <xsd:attribute name="stylePrimaryName" type="xsd:string"/>
  <xsd:attribute name="title" type="xsd:string"/>
  <xsd:attribute name="visible" type="xsd:string"/>
  <xsd:attribute name="width" type="xsd:string"/>
  <xsd:attribute name="j_name" type="xsd:string"/>
  <xsd:attribute name="addStyleNames" type="xsd:string"/>
  <xsd:attribute name="addStyleDependentNames" type="xsd:string"/>
</xsd:complexType>

<xsd:complexType name="WidgetType">
  <xsd:complexContent>
    <xsd:extension base="UIObjectType">
    </xsd:extension>
  </xsd:complexContent>
</xsd:complexType>

LablelType for Label:

<xsd:complexType name="LabelType">
  <xsd:complexContent>
    <xsd:extension base="WidgetType">
      <xsd:attribute name="direction" type="xsd:string"/>
      <xsd:attribute name="horizontalAlignment" type="xsd:string"/>
      <xsd:attribute name="text" type="xsd:string"/>
      <xsd:attribute name="wordWrap" type="xsd:string"/>
      <xsd:attribute name="onClick" type="xsd:string"/>
      <xsd:attribute name="onMouseDown" type="xsd:string"/>
      <xsd:attribute name="onMouseMove" type="xsd:string"/>
      <xsd:attribute name="onMouseOut" type="xsd:string"/>
      <xsd:attribute name="onMouseOver" type="xsd:string"/>
      <xsd:attribute name="onMouseUp" type="xsd:string"/>
      <xsd:attribute name="onMouseWheel" type="xsd:string"/>
      <xsd:attribute name="pattern" type="xsd:string"/>
    </xsd:extension>
  </xsd:complexContent>
</xsd:complexType>

Basically, gwtXP file consist of

  • A root element <g:gwtxp controllerClassName=”qualified class name”>
  • A UI root element, normally it is sub-class of Panel.
  • And UI hierarchy in the UI root element.

Review HelloWorld example

Let review the generated code for HelloWorld.gwtxp.xml file in the Getting Started section.

<?xml version="1.0" encoding="UTF-8" ?>
<g:gwtxp xmlns:g="http://www.gdevelop.com/gwtxp"
  controllerClassName="com.gdevelop.samples.hello.client.HelloController">

<g:verticalPanel width="100%">
 <g:textBox enabled="true"/>
 <g:button text="${constants.greeting}" onClick="#{sayHello}"/>
</g:verticalPanel>
</g:gwtxp>

As you can see in the XML file structure, the root element is a VerticalPanel with two children, a TextBox and a Button.

The generated code is as below:

public class Hello_GwtXP
  extends com.gdevelop.samples.hello.client.HelloController
  implements com.gdevelop.gwtxp.client.GwtXP{
...
public UIObject getGUI(){
  if (__guiObject__ == null ){
    __guiObject__ = __initGUI__();
  }
  return __guiObject__;
  }

private UIObject __initGUI__(){
  // g_verticalPanel_0
  __guiObject__ = g_verticalPanel_0;
  g_verticalPanel_0.setWidth("100%");
  g_verticalPanel_0.add(g_textBox_0);

  // g_textBox_0
  __uiNameMap__.put("g_textBox_0", g_textBox_0);
  g_textBox_0.setEnabled((Boolean)
    Converters.getConverter(String.class, Boolean.class).convert("true"));
  g_verticalPanel_0.add(g_button_0);

  // g_button_0
  __uiNameMap__.put("g_button_0", g_button_0);
  g_button_0.setText(__this__.getConstants().greeting());
  g_button_0.addClickHandler(new ClickHandler(){
    public void onClick(ClickEvent event){
      __this__.sayHello();
    }
  });

  return __guiObject__;
}
...
}

Note: The generated class extends the Controller class specified in controllerClassName attribute in gwtxp file.

Setting up widget properties

You can set the widget’s property by setting element’s attribute in definition file. The widget’s property value can be

  • A literal: for example  “100%”, true, etc
  • GWT’s constant: for example ${constants.greeting}
  • Dynamically bound to a bean’s property by a Expression: for example ${user.name}

Literals

GwtXPGenerator will generate code to set value to widget’s property. In case widget’s property type is not String, GwtXPGenerator will generate Converter code to convert attribute String value to appropriate type before setting to widget’s property.

In HelloWorld example, the generated code look like

g_verticalPanel_0.setWidth("100%");  // No conversion required.
  ...
// Converter is used to convert String to Boolean
g_textBox_0.setEnabled((Boolean)
  Converters.getConverter(String.class, Boolean.class).convert("true"));

Constants

For constants, the Controller class must have a get method which return type of com.google.gwt.i18n.client.Constants.

In HelloWorld example, the generated code is as below

g_button_0.setText(__this__.getConstants().greeting());

Expression

We can also use an Expression to set widget’s property.
See Data Binding

Actions and Handlers

gwtXP generate code to register handlers to the widgets. The handler in turn will call appropriate Controller method for handling user’s actions.

In our HelloWorld example, the generated code for onClick=”#{sayHello}” is as below

g_button_0.addClickHandler(new ClickHandler(){
  public void onClick(ClickEvent event){
    __this__.sayHello();
  }
});

Note: gwtXP uses ${...} notation for data bindings and #{...} notation for event handlers.

Next: see following sections for details about setting up widget’s properties, data binding and event handler methods.

 

Share and Enjoy:

  • Google Bookmarks
  • Twitter
  • Facebook
  • Digg
  • Technorati
  • Live
  • DZone
  • Reddit
  • del.icio.us
  • Mixx
  • Netvibes
  • StumbleUpon
  • Yahoo! Bookmarks
  • Yahoo! Buzz
  • email