Tuesday, December 23, 2008

A Groovy ZK Builder

I have built a Groovy builder for the ZK tool set.

Motivation
While using ZK with Grails, I found that I was using a lot of Java object building inside of ZK Composer objects. This leads to a profusion of code like the following:


Listbox lb = new Listbox();
Listhead lh = new Listhead();
lh.setParent(lb);
Listheader idHeader = new Listheader('id');
Listheader nameHeader = new Listheader('name');
idheader.setParent(lh);
nameHeader.setParent(lh);

And as XML

<listbox>
<listhead>
<listheader label="id">
<listheader label="name">
</listhead>
</listbox>


As you can see there is a profusion of boilerplate code that is the hallmark of a nested Java API. The XML is easier on the eye and hides setting parent references. What I really wanted was something like the simplicity of the XML with the flexibility inherent in Groovy closures.

Groovy ZkBuilder
The builder's syntax is very similar to the XML.


ZkBuilder zk = new ZkBuilder()
Window w = zk.window {
listbox('actionBox') {
listhead(){
listheader(label: 'Action')
}
}
button() {
onClick { event ->
def item = listitem() {
listcell(label: "$event.name on $event.date")
}
item.parent = actionBox
}
}
}


Features
  1. All the basic Zul and Zhtml elements as of 3.52 (Not all tested yet). Where there is a namespace collision, prefix html on zhtml elements to get the html version: htmlLabel or htmlDiv.
  2. The first string argument to any builder is the components id. The component can be accessed by that id from that point on in the builders. See the use of actionBox in the onClick handler.
  3. Properties of the component / object are set using the Groovy map syntax as an argument to its method call: listbox(visible: false)
  4. The component / object produced by the builder is available as the argument to its closure. This allows for more complex initialization of an object than attributes alone will allow.
  5. The event listener creation syntax allows access to all components / object created with ids. It also has a builder that produces components that are not set to the parent object. This allows you to create components in event listeners that can be attached to any id based component and not just the parent.
  6. Event listeners can also be assigned through the map syntax. If these events are not closures they have to use the standard ZK way to access other components.
Where to get it?
I have put up a google code site to host the builder an any other code that I end up developing that would be best shared with the community at large.


No comments: