CookSwt Tutorial: Tag Extension



Support This Project


stats counter


Logo Logo IntelliJ IDEA


CookSwt is an extension of CookXml in that it provides a tag library that defines the XML schema. CookXml itself does not provide any tag libraries, but rather the interfaces and some generic functional objects for use with extensions. CookSwt also extends the TagLibrary used by CookXml such that it is possible to have tag inheritance, which we will discuss below.

Some Definitions

A TagLibrary is a collection of function/factory objects that creates and manipulate objects.

A Creator is a factory object which generates an object of the interest for a given element.

A Setter is a function object which sets an attribute of a object.

An Adder is a function object which adds a child object to the object.

A Converter is a function object which converts a string to an data type corresponding to the target class.

Creators, Setters, Adders and Converters make up a TagLibrary. As for tag inheritance, the child (in terms of inheritance hierarchy) tag inherits all the adders and setters of the parent tag. Multiple inheritance is allowed in the CookSwing InheritableTagLibrary.

Below are the guides of creating the components of a TagLibrary.


All tags must have a Creator. Some can be easily created, while some are not.

The Simplest Case

For classes that have a default constructor and the objects that can be modified later, CookXml provides a DefaultCreator that can be used to add a new tag element to the tag library. For example:

	tagLibrary.setCreator ("point", DefaultCreator.getCreator (Point.class));

Here, a new tag point is created. Whenever an XML document contains a <point> tag, this Creator object is called and a new Point object is created.

There are certain traps, however, which you may encounter occasionally. By default, as soon as an object is created and its setters are called, it is added to the parent object, without considering the descendent nodes. As the result, if the parent node process the object immediately, it may not see a full picture. In those cases, it is necessary to delay the addition of the object to its parent. For example:

	tagLibrary.setCreator ("vector", DefaultCreator.getCreator(Vector.class, true));

No Default Constructor?

Some classes, such as Swing's BoxLayout, which does not have a default constructor that takes no parameters, it is necessary to have a custom Creator which takes the constructor tag value and determine parameters for the object constructors. Here is an actual code for the BoxLayoutCreator class. Many classes, notably immutable object classes such as Boolean, Integer, etc, can be created using this approach. However, it can be unintuitive for the author of the XML document to use the constructor tag.

In case of SWT widgets, which all needs to have the parent widget and the style information when they are created, it might be easier to just write a generic creator, in this case, WidgetCreator to take care it.

Helper Needed

Sometimes, there can be too many fields need to be setup before an actual object could be generated. In these cases, helper comes handy to temporarily collect the attribute settings done before actually creating the object. A good example is CursorHelper, which is used by CursorCreator. It should be noted, however, if the child of this object requires to know the actual constructed parent, then this approach is not viable.


Generally, one does not need to write a setter for a class, as the default setter automatically searches for the appropriate variables/setter functions that can handle the attribute.

Constant Setter

It is often preferred to use names such as "CENTER" rather than the hard coded value 1 to assign attribute values. In those cases, ConstantSetter comes handy.

	ConstantSetter swtConstantSetter = new ConstantSetter (SWT.class);
	tagLibrary.setSetter ("button", "alignment", swtConstantSetter);

In the above example, the first line creates a setter which will lookup names in the static field of SWT. The second line tells CookXml to hook the setter to the attribute name of "alignment" for the "label" tag.


By default, there is a DefaultAdder which looks up public functions with the name add and the appropriate parameter class type for the object. Thus, if there are functions add (String title) and add (Image image) and the current object is a string, then the first function is called. In many cases, the function you want to call may be different from add, so it is desirable (but not required, since you can use the "func" attribute in the object to specify the function to be called) to have an adder for the task, making it easier for the author of the XML document. A simple example is ComboBoxAdder.

While CookXml only provides a setAdder function which can only associate one Adder with a class, the InheritableTagLibrary also provides addAdder function so that multiple adders could be composed together to function as one.


The main purpose of using Converter is to simplify writing the XML document. For example, even though we can set the rows of a grid layout using

		<int setas="numcolumns" value="2">

. The following approach is so much simpler and more intuitive.

	<gridlayout numcolumns="2">

Writing a Converter is really easy, as evidented by the IntConverter.

(c) Copyright 2004-2007 Heng Yuan. All rights reserved.

Valid XHTML 1.0! Valid CSS!