What's new? | Help | Directory | Sign in
Google
google-web-toolkit-incubator
Likely additions to Google Web Toolkit
  
  
  
  
    
Search
for
Updated Jul 01, 2008 by rj...@google.com
Labels: Type-Library
DeclarativeUi  
Declarative XML structure for defining GWT widgets

There is a more up to date set of use cases at UiBinder

Declarative UI Construction in GWT

Joel Webber

Motivation & Use Cases

Writing imperative Java code to construct a user-interface hierarchy is awkward, and it makes working with UI designers difficult and/or impossible. What we want is to provide designers (and developers) with a simple way to define the static structure of applications and widgets, without having to write code.

It seems natural to define UI structure at the granularity of Composites. This will make it easy to define either entire applications declaratively, as well as simple widgets. It also provides a natural model for composing large structures from small ones, and for refactoring complex UI structures.

Imagine the following use pattern:

1. Designer creates a mock in Photoshop, Dreamweaver, ...

mymock.html

<html><body>
  <!-- A tree of buttons -->
  <div><div><button>Do something</button>...
</body></html>

2. Developer and/or designer massages this into a GWT template for a page-like Widget

App.ui.xml

<g:HTML xmlns:g='http://code.google.com/webtoolkit/com.google.gwt.user.client.ui'>
  <!-- A tree of buttons -->
  <div><div><button>Do something</button>...
</g:HTML>

App.java

class App extends Composite implements EntryPoint, Template {
  public void onModuleLoad() {
   // ...
  }
}

3. The template XML file can now run in the GWT hosted browser (a few clicks and/or command-line exec)

4. Developer and/or designer identifies Widget-like structures (including Panel-like structures, etc.) and factors them out into other templates

App.ui.xml

<!-- Note how we add a new namespace for the application's package -->
<app:ButtonTree
  xmlns:g='http://code.google.com/webtoolkit/com.google.gwt.user.client.ui'
  xmlns:app='http://code.google.com/webtoolkit/com.example.myapp.client'
/>

ButtonTree.ui.xml

<g:Tree xmlns:g='http://code.google.com/webtoolkit/com.google.gwt.user.client.ui'>
  <g:TreeItem>
    <g:Button>Do something</g:Button>
  </g:TreeItem>
</g:Tree>

5. Still runnable!

6. Goto 3

Goals and Non-goals

Goals:

Non-Goals:

A Simple Example

In this rather contrived example, we define a simple labeled text box using HTML and TextBox widgets embedded in a HorizontalPanel.

EditableTextBox.ui.xml:

<g:HorizontalPanel xmlns:g='http://code.google.com/webtoolkit/com.google.gwt.user.client.ui'>
  <g:HTML id='label'>This <em>text box</em> is editable:</g:HTML>
  <g:TextBox id='editor'/>
<g:HorizontalPanel>

EditableTextBox.java:

public abstract class EditableTextBox extends Composite implements Template {

  public static EditableTextBox create() {
    return (EditableTextBox) GWT.create(EditableTextBox.class);
  }

  public EditableTextBox() {
    getEditor().setText("default text");
  }

  public void setCaption(String captionHTML) {
    getCaption().setHTML(captionHTML);
  }

  public String getValue() {
    return getEditor().getText();
  }

  protected abstract HTML getCaption();
  protected abstract TextBox getEditor();
}

A More Complex Example

Here, we have an example of a composite that would define the outer superstructure of an application.

A couple of important things to notice here:

App.ui.xml:

<g:HTMLPanel xmlns:g='http://code.google.com/webtoolkit/com.google.gwt.user.client.ui'>
  <div class='banner' style='width:100%'>
    <img src='myLogo.gif'/>
    Welcome to my application. It's really cool.
  </div>

  <g:MenuBar>
    <g:MenuItem caption='file'>
      <g:MenuBar>
        <g:MenuItem caption='open'/ id='openMenu'>
        <g:MenuItem caption='close' id='closeMenu'/>
        <g:MenuItem caption='exit' id='exitMenu'/>
      </g:MenuBar>
    </g:MenuItem>
  </g:MenuBar>

  <div class='app' style='width:100%'>
    <g:TabPanel id='tabs'>
      <g:Tab>
        <g:TabCaption><em>Main</em></g:TabCaption>
        <g:MainComposite id='main'/>
      </g:Tab>
      <g:Tab>
        <g:TabCaption><em>Settings</em></g:TabCaption>
        <g:SettingsComposite id='settings'/>
      </g:Tab>
    </g:TabPanel>
  </div>
</g:HTMLPanel>

App.java:

public abstract class App extends Composite implements Template {

  public static App create() {
    return (App) GWT.create(App.class);
  }

  public App() {
    getExitMenu().setCommand(new Command() {
      public void execute() {
        // Exit the app.
      }
    });

    // etc...
  }

  protected abstract MenuItem getOpenMenu();
  protected abstract MenuItem getCloseMenu();
  protected abstract MenuItem getExitMenu();
  protected abstract TabPanel getTabs();
  protected abstract MainComposite getMain();
  protected abstract SettingsComposite getSettings();
}

Restrictions and Caveats

Because it uses a generator, composites defined this way must be created using GWT.create(). This also implies that they must have a no-argument constructor (because you cannot pass parameters to GWT.create(). A simple way to make this a little cleaner is to create a public static create() method, so that the site of instantiation just looks like MyWidget w = MyWidget.create().

public static MyWidget create() {
  return (MyWidget)GWT.create(MyWidget.class);
}

Widgets instantiated by a template composite must also have a no-argument constructor, because the code generator doesn't know what arguments to pass to them (This restriction can be worked around with a custom parser; see below).

Implementation Details

As shown above, the composite base class implements 'Template', which is simply a tag interface that triggers a generator. The generator will find the associated ui.xml and generate a concrete implementation that constructs the widget hierarchy and implements all of the widget getter methods().

(More to come on how the xml gets parsed, how xml structures are defined for widgets, and so forth)

Open Questions


Comment by jwarnica, Oct 04, 2007

How serious is this being proposed? Is there, say a 100% chance that it will happen in 5 years, or a random idea that isn't likely to ever move beyond this page?

Comment by gwt.team.ajr, Oct 16, 2007

It's not just a proposal -- Joel is working on it!

Comment by J.Alkjaer, Oct 18, 2007

@joel - any news?

Comment by miguel.ping, Nov 08, 2007

As for the img bundle support, here's a simple idea:

  • you declare an img bundle tag:
  • <g:Img bundle='bundle1' id='myImg'>
  • you declare an image bundle bundle1 in your source code:
  • MyImageBundle bundle1 = GWT.create(MyImageBundle);
  • Bundle1 has an image called myImg:
  • public interface MyImageBundle extends ImageBundle {
      AbstractImagePrototype myImg();

The rest is already implemented.

Comment by sthamman, Dec 04, 2007

Is the code available for us to use the DeclarativeUi?

Comment by olostan, Jan 17, 2008

Something like that I've been implemented in 'gwt-ui' project: http://code.google.com/p/gwt-ui/

But main idea of gwt-ui was not 'declarative ui', but 'declarative states'. But idea and code of 'gwt-ui' can be simply updated to implement idea of 'declarative ui'

Comment by gilles.ducret, Feb 12, 2008

Is this a project that will be implemented soon? I would have this need and it would be great if I could use GWT and declare UI in XML.

Comment by wangzaixiang, Feb 13, 2008

The proposal is so exciting to make GWT more friendly to developer. also, a IDE plugin to preview the declarativeUI would makes code more WYSIWYG.

Comment by denis.tsyplakov, Apr 07, 2008

Great feature!

Comment by tmnichols, Apr 08, 2008

This would be an awesome feature and probably the only reason I didn't jump into GWT from the beginning -- Declarative is by far a better way to define UIs. Let's hope this gets released soon!

Comment by vicente.ordonez, Apr 24, 2008

Declarative UI or not.. anyone has experience with both? I have seen that Echo2 was working just by writing code in Java but then they moved to declare things in Javascript. Ext has been moved to Gwt, since they have kind of declarative Javascript. Backbase has declarative XML like format. For complex things does dreamweaver really works? I think at the very end web developers will have to totally separate the design thing just as a matter of creating a raw image output of how an application looks like and then hire a programmer to make that design a reality into the application and at the same time make it modifiable, which is a pain but for facebook-like applications I think it is worth the time

Comment by chenhenri, May 08, 2008

The ZK Ajax framework has adopted this concept since day 1 and it is really useful and convenient. However, what I want to say is that all these declarative UI tags should come out some sort of standards, (e.g. XUL) that users don't have to learn several tag set.

Comment by meident69, May 26, 2008

Agreed. Definitely need some standardization on the declarative ui markup languages already around.

http://en.wikipedia.org/wiki/List_of_user_interface_markup_languages

Comment by meident69, May 26, 2008

i was reading the Andriod site and they mentioned something about XML UI markup as well. It seems it's extremely simple right now with a few UI elements and controls. Is this project related to that one?

Comment by robert.chou, Jun 10, 2008

Here's a XulGuiBuilder? implementation that takes a xul file and a GWT panel and builds GWT widgets based on the xul file into the GWT panel. You then look up the xul ID of each widget to populate data, set listeners, etc... The designer can focus on layout without code and the developer connects things up. Like the old windows resource file for GUI days.

I wrote this idea up when GWT first came out 2 years ago for another project but decided to stay with my existing framework because GWT did not have enough widgets so the code stayed dormant.

Now that I see others are talking about similar ideas, I'm happy to contribute to share. The zip file belong contains the entire netbeans 6.1 project. You can also run it from the command line via "MainEntryPoint?-shell.cmd" (must have gwt installed of course). http://www.killaman.com/GwtUtils.zip

In the sample web app, click on the "XUL samples" link. Each button loads another xul file and builds the widgets in the content area. Also, the "XUL Preview" link has a LIVE preview area where you can type XUL and get an instant preview by pressing the Preview button (the preview will show up in a popup, this needs server support so you need to run via the .cmd and not just browse to the html pages unlike the xul samples which work without a server).

Here's some sample code:

// create panel to hold content Panel output = new VerticalPanel?(); initWidget( output );

// load content XulGuiBuilder?.AsyncPanelHandler? panelHandler = new XulGuiBuilder?.AsyncPanelHandler?() {
public void onSuccess(String string, Panel panel) {
// extract fields m_lblNavFirst = (Label)GwtWidgetUtils?.getWidgetById( panel, "navFirst" ); m_lblNavFirst.addClickListener( new ClickListener?() {
public void onClick(Widget sender) {
navigateTo( PAGE_FIRST );
}
} );
...
}
public void onFailure(String string) {
// error already logged, content set to error message
// do your stuff ...
}
}; XulGuiBuilder? xulGuiBuilder = XulWidgetFactory?.getSingleton().createXulGuiBuilder(); xulGuiBuilder.createPanelContentFromXulUrl( output, "search_table.xul", panelHandler );

Robert

Comment by robert.chou, Jun 10, 2008

Hmm... the sample code lines got run together by the wiki... Well, here are 2 screen captures:

Comment by jackieanstey, Jun 23, 2008

Robert - I tried to download your sample (GwtUtils?.zip) - but it's telling me "page not found".

Comment by waylonflinn, Jun 24, 2008

Wouldn't it be the sweetness if GWT declarative ui was (easily) mappable to Android declarative ui?

I'm involved in a project attempting to target both platforms from a single code base right now and having this sort of consistency could potentially reduce initial investment and maintenance overhead significantly.

For those unfamiliar with Android ui design an example (and links to more info) can be found at the following URL: http://code.google.com/android/devel/ui/xml.html

Comment by cignini, Jun 29, 2008

It's from January 2007 that I'm working with GWT and now I think that an XML approach for UI generation is a must if you want to develop a really big application with it.

Some months ago I've started to work on a Declarative XML UI approach for GWT. The result is a first library based on the ideas described in this page and some ideas that I've collected during this year. In my approach the XML that you can write have a lot of similarities with XSLT: there are templates, variables, parameters, actions and GWT components like Panels, TextBox???, CheckBox???, etc.

In my implementation you can decide if the XML is store with the compiled javascript or you can retrieve it from the server on runtime in order to generate dynamically user interfaces as GWT widgets accessible later like the Template approach described here.

The good think is that GWT code contains only the logic of your application and you can delegate a lot of part of the UI generation to the XML-GWT UI builder.

Now I've started to use it on a first real project.

It's difficult to explain all ideas behind my approach, but I hope to receive feedbacks about it.


Sign in to add a comment