The current version of GXT was created prior to GWT 2.0 UiBinder, so it does not implement the proper interfaces, such as HasWidgets, to behave properly in UiBinder. This means that when a project needs to add GXT layouts and widgets, it all needs to be done programmatically in the "View" class rather than declaratively in XML. This causes a huge burden on the developer.
With my recent work on adding custom UiBinder ElementParsers for GWT, I have been able to add new ElementParsers for the ExtGWT framework to make working with GXT widgets in UiBinder much more friendly. This project has been released as gxt-uibinder.
Getting Started
First, you must inherit the module. Since this library uses gwt-customuibinder to register custom ElementParser classes, this module must be inherited after all other <inherit> lines.
For example:
<module> <inherits name="com.google.gwt.user.User" /> <inherits name="com.extjs.gxt.ui.GXT" /> <inherits name="com.jhickman.web.gwt.gxtuibinder.GxtUiBinder" /> <source path="client" /> <source path="shared" /> </module>
Supported Components
As this is a fairly new project, not all components are supported. The most important one, however, is the ContainerParser for subclasses of the Container component.
Container
Since most of the "panels" in GXT (such as LayoutContainer, ContentPanel, etc) extend Container, then all of these these will support nested children.
LayoutContainer
GXT LayoutContainer subclasses Container, so all of the above apply here as well. The major difference, however, is the ability to apply different "Layouts".
Currently, there are 2 supported Layouts: FitLayout and BorderLayout. Below shows examples of both.
FitLayout
<gxt:LayoutContainer layout="FitLayout"> <Label text="Hi" /> </gxt:LayoutContainer>
BorderLayout
BorderLayout supports layout regions as child elements. This means that the children of a LayoutContainer using the BorderLayout must be one of <gxt:center>, <gxt:west>, <gxt:north>, <gxt:east>, and <gxt:south>. Each region can only appear once, but may appear in any order.
Also note that each region, except <gxt:center> must specify a size attribute, specified in pixels. These regions also support the folling attributes:
- split
- boolean value. true if resizable split panel is needed.
- collapsible
- boolean value. true if the panel should contain the collapse button.
- margins
- can be specified as a single integer (ie margins="5") to make all margins the same, or a comma separated list of 4 integers (ie margins="0,5,0,0"). The order is top, right, bottom, left
<gxt:LayoutContainer layout="BorderLayout"> <gxt:north size="30"> <gxt:ContentPanel>...</gxt:ContentPanel> </gxt:north> <gxt:center> <gxt:ContentPanel>...</gxt:ContentPanel> </gxt:center> <gxt:east size="50" split="true" collapsible="true"> <gxt:ContentPanel>...</gxt:ContentPanel> </gxt:east> </gxt:LayoutContainer>
ContentPanel
GXT ContentPanel subclasses LayoutContainer, so all of the above apply here as well. The ContentPanel supports specifying top and bottom components. This is typically used for status bars or toolbars. This can be done by using the child elements: <gxt:topcomponent> and <gxt:bottomcomponent>. These are optional children, and may appear only once each.
For example:
<gxt:ContentPanel heading="Admin Scripting Console"> <gxt:topcomponent> <menu:MenuBar borders="true" /><!-- menu explained below --> </gxt:topcomponent> </gxt:ContentPanel>
Menus
GXT menus are also supported. Here is an example of its usage:
<gxt:ContentPanel heading="Some Panel"> <gxt:topcomponent> <menu:MenuBar borders="true"> <menu:MenuBarItem text="File"> <menu:Menu> <menu:MenuItem text="New" ui:field="newMenuItem" /> <menu:MenuItem text="Open" ui:field="openMenuItem" /> <menu:MenuItem text="Save" ui:field="saveMenuItem" /> <menu:MenuItem text="Save As" ui:field="saveAsMenuItem" /> <menu:CheckMenuItem checked="true" /> </menu:Menu> </menu:MenuBarItem> </menu:MenuBar> </gxt:topcomponent> <gxt:LayoutContainer layout="BorderLayout"> <gxt:center> <gxt:LayoutContainer layout="FitLayout"> <gxt:Label> </gxt:LayoutContainer> </gxt:center> </gxt:LayoutContainer> </gxt:ContentPanel>
Custom Event Handling
The GXT event model differs from GWT. This means that the @UiHandler annotation cannot be directly used to apply widget event handlers back to the owning view class.
For this, I have created a new annotation that can be used for GXT widget event binding. It's called @GxtUiHandler.
For example, let's say in the UiBinder XML, you have a GXT button that needs to execute. In the XML, the ui:field is used as normal.
<gxt:Button text="submit" ui:field="submitButton" />
In the owning view Java class, a method to receive the event will have the @GxtUiHandler annotation applied as such:
@GxtUiHandler(uiField="submitButton", eventType=GxtEvent.Select) public void submitForm(ButtonEvent event) { System.out.println("form Submitted"); }
Unlike the @UiHandler annotation, we have to tell the compiler what Event type it relates to. This is the major difference between @GxtUiHandler and @UiHandler annotations.
Summary
This library is still in early development, so does not yet support all GXT widgets and properties, but it may have enough for any project to get started with using GXT in their UiBinder XML files.