UiBinder integration with lib-gwt-svg

Beginning with version 0.4 of lib-gwt-svg, UiBinder templates can be used to integrate SVG into GWT applications. Two new classes have been introduced to enable this:

org.vectomatic.dom.svg.ui.SVGImage is a widget which contains a single <svg> element. It can be instantiated and added to a GWT widget hierarchy just like any other Widget subclass: Button, Label, ListBox
org.vectomatic.dom.svg.ui.SVGResource enables putting SVG resources in a GWT client bundle. It can be added to a ClientBundle just like any other resource type: TextResource, CssResource, ImageResource

These classes can be used in UiBinder templates to create differente patterns of SVG-GWT integration

GWT references to external resources

Using this pattern, the SVG file is put in the same location as the other resources of the project (PNG, CSS…). The GWT compiler will compile the SVG code into the application, so it does not have to be downloaded separately when the application starts. This style is suitable if your application only needs to display an SVG file in its user interface.

ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
 xmlns:g='urn:import:com.google.gwt.user.client.ui'
 xmlns:svg='org.vectomatic.dom.svg.ui'>
 <ui:with field='resources'
 type='org.vectomatic.svg.samples.client.widgets.WidgetSamplesBundle' />
 <g:VerticalPanel>
   <svg:SVGImage ui:field="myImage" resource="{resources.hearts}"/>
 </g:VerticalPanel>
</ui:UiBinder>
public interface WidgetsSampleBundle extends ClientBundle {
    public static WidgetsSampleBundle INSTANCE = GWT.create(WidgetsSampleBundle.class);
   
    @Source("as_coeur_jean_victor_bal_.svg")
    SVGResource hearts();
}

Embedding SVG directly in the UiBinder template

The SVG is embedded directly in as a child of the SVGImage declaration. Notice several powerful features.

  • You can bind arbitrary SVG child elements to instance variables of your UI controller. This binding using XPaths internally, so this does not prevent you from putting ‘id’ attributes in your SVG elements. You can use the following svg tag to gwt class mapping to determine the type to use for GWT variables.
  • UiBinder can attach event handlers automatically to arbitrary SVG child elements using the @UiHandler annotations
  • You can externalize your SVG styles using UiBinder styling mechanisms (using the ui:style declaration or compiled CSS resources.
  • You can localize your SVG files using UiBinder ui:msg facilities

This pattern provides for a much tighter integration with UiBinder and enables leveraging the strengths of GWT.

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
 xmlns:g='urn:import:com.google.gwt.user.client.ui'
 ui:generateFormat='com.google.gwt.i18n.rebind.format.PropertiesFormat'
 ui:generateKeys="com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator"
 ui:generateLocales="default">
  <ui:with field='style' type='org.vectomatic.svg.myCss'/>
  <g:VerticalPanel>
    <svg:SVGImage>
      <svg width="400px" height="400px" xmlns="http://www.w3.org/2000/svg">
    <rect ui:field="myRect" class="{style.rectStyle}" x="10" y="20" width="79" height="90"/>
        <text x="10" y="40"><ui:msg description="Greeting">Hello, world.</ui:msg></text>
      </svg>
    </svg:SVGImage>
  </g:VerticalPanel>
</ui:UiBinder>
@UiHandler("myRect")
public void mouseDown(MouseDownEvent event) {
}

warning The UiBinder integration uses a custom UiBinder element parser. Since custom element parsers are not yet supported in GWT (the public API for this feature is scheduled for GWT 2.1), lib-gwt-svg contains several classes which patch gwt-user.jar to invoke the custom element parser (reusing a mechanism first proposed by the gwt-mosaic project). Thus, for your project to work, the lib-gwt-svg.jar must appear before gwt-user.jar in the classpath so that the patched classes can take precedence over the official GWT classes. This problem ought to be solved when GWT 2.1 is released.

Creating SVG push buttons and toggle buttons

Beginning with lib-gwt-svg version 0.4.5, it is now possible to create SVG push buttons and toggle buttons. SVG buttons consists in an SVG element and a collection of six predefined faces

  • UP
  • UP_DISABLED
  • UP_HOVERING
  • DOWN
  • DOWN_DISABLED
  • DOWN_HOVERING

Each face consists in a list of changes which are applied to the main SVG element (currently, CSS style changes but other changes are possible). You do not need to specify all faces for a button. In case a face is missing, the widget will attempt to use another face for the button.

An org.vectomatic.dom.svg.ui.SVGPushButton typically defines at least the following two faces:

  • UP
  • DOWN_HOVERING

An org.vectomatic.dom.svg.ui.SVGToggleButton typically defines at least the following two faces:

  • UP
  • DOWN

To define SVG faces in UiBinder, use the svgui:up, svgui:upDisabled, svgui:upHovering, svgui:down, svgui:downDisabled and svgui:downHovering tags.

Depending on your needs, you can either define the SVG inline with the svgui:element tag. This can be convenient if you want to localize the button label, or use styles defined in the template. Or you can use an org.vectomatic.dom.svg.ui.SVGResource with the resource attribute, if your SVG is large or if you want to keep your template more readable.

Each face contains one or more svgui:styleChange tags. The classNames attribute specifies the name of the CSS class selectors to be applied to the SVG element when the face is activated.

The following section shows a sample UiBinder template for a push button with an in-line SVG element:

<svgui:SVGPushButton ui:field="clickMeButton">
   <svgui:element>
     <svg viewBox="0 0 200 60" width="200" height="60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
       <rect class="btn-shape" x="3" y="3" width="194" height="54" rx="10" ry="10" />
       <text class="btn-text" x="16" y="43">Click me !</text>
      </svg>
   </svgui:element>
   <svgui:upFace><svgui:styleChange classNames="{style.btn1} {style.btn1-up}"/></svgui:upFace>
   <svgui:downHoveringFace><svgui:styleChange classNames="{style.btn1} {style.btn1-down-hovering}"/></svgui:downHoveringFace>
 </svgui:SVGPushButton>

The following section shows a sample UiBinder template for a toggle button with an SVG element defined by an org.vectomatic.dom.svg.ui.SVGResource:

<svgui:SVGToggleButton resource="{resources.led}">
  <svgui:upFace><svgui:styleChange classNames="{style.led-up}"/></svgui:upFace>
  <svgui:downFace><svgui:styleChange classNames="{style.led-down}"/></svgui:downFace>
 </svgui:SVGToggleButton>

Samples

Samples demonstrating these integration patterns can be executed online (see the “widgets” tab of the lib-gwt-svg-samples application)