|
IntroductionCookXml core component itself does not provide any tag libraries, but rather the interfaces and some generic functional objects for use with extensions. The common component defines some commonly used tags and converters for projects like CookSwing and CookSwt to use. CookXml core component defines a simple TagLibrary, while the common component extends it such that it is possible to have tag inheritance, which we will discuss below. Some DefinitionsA 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 common component's InheritableTagLibrary. Below are the guides of creating the components of a TagLibrary. CreatorAll tags must have a Creator. Some can be easily created, while some are not. The Simplest CaseFor 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 ("menu", DefaultCreator.getCreator (JMenu.class)); Here, a new tag 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 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. Helper NeededSometimes, there can be too many fields need to be setup before an actual object could be generated. In these cases, helper objects are needed to temporarily collect the attribute settings done before actually creating the object. A good example is TitledBorderHelper, which is used by BorderCreator. SetterGenerally, 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 SetterIt is often preferred to use names such as "VERTICAL" rather than the hard coded value 1 to assign attribute values. In those cases, ConstantSetter comes handy. ConstantSetter swingConstantsSetter = new ConstantSetter (SwingConstants.class); tagLibrary.setSetter ("toolbar", "orientation", swingConstantsSetter); In the above example, the first line creates a setter which will lookup names in the static field of SwingConstants. The second line tells CookXml to hook the setter to the attribute name of "orientation" for the "toolbar" tag. AdderBy default, there is a DefaultAdder which looks up
public functions with the name 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. ConverterThe 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 <gridlayout> <int setas="rows" value="2"> <int setas="columns" value="2"> . The following approach is so much simpler and more intuitive. <gridlayout rows="2" columns="2"> Writing a Converter is really easy, as evidented by the IntConverter.. |