Tutorial 1: A Simple Menu Loader


 

 

Support This Project

 

stats counter

 

Logo SourceForge.net Logo IntelliJ IDEA

Introduction

In this tutorial, I will show you how to use CookXml to create a tag library that loads XML document like the following into a Swing JMenuBar.

<?xml version="1.0"?>
<menubar>
	<menu text="File">
		<menu text="Open">
			<menuitem text="XML"/>
			<menuitem text="Java"/>
		</menu>
		<menuitem text="Exit"/>
	</menu>
	<menu text="Edit">
		<menuitem text="Cut"/>
		<menuitem text="Copy"/>
		<menuitem text="Paste"/>
	</menu>
	<menu text="Help">
		<menuitem text="About"/>
	</menu>
</menubar>

For other XML data binding toolkits, you will need the XML schema for it. There are tools out there that can take this sample XML and generate an XML schema, but for CookXml it is not necessary. For other XML toolkits, you will also be responsble for mapping the generated classes into the corresponding JMenuBar, JMenu and JMenuItem classes. For CookXml, the XML elements are directly mapped to these three classes.

This tutorial only requires the CookXml core library.

Step 1: Creating a TagLibrary

The very first step of of using CookXml is to create a tag library that will hold all the definitions. Here since we are not dealing XML namespaces, we have two choices: SingleNSTagLibrary or InhertiableTagLibrary. InheritableTagLibrary is more powerful than SingleNSTagLibrary, but for our simple example, SingleNSTagLibrary is suffice.

SingleNSTagLibrary tagLibrary = new SingleNSTagLibrary ();

Step 2: Tag Creators

Creators are object factories which tell CookXml how to create an object when a DOM element is encountered.

We will map <menubar> to JMenuBar, <menu> to JMenu and <menuitem> to JMenuItem. These three classes all have default constructors, so we can use DefaultCreator class to generate creators for us.

tagLibrary.setCreator ("menubar", DefaultCreator.getCreator (JMenuBar.class));
tagLibrary.setCreator ("menu", DefaultCreator.getCreator (JMenu.class));
tagLibrary.setCreator ("menuitem", DefaultCreator.getCreator (JMenuItem.class));

Step 3: Setters

Setters are used to modify objects based on attributes. In our cases, both <menu> and <menuitem> have text attribute. If DefaultSetter is used, then CookXml looks for either an accessible text variable or a public setText (parameter) function through Java reflection. Conveniently, both JMenu and JMenuItem has setText function, so we can use the DefaultSetter for both.

tagLibrary.setSetter ("menu", "text", DefaultSetter.getInstance ());
tagLibrary.setSetter ("menuitem", "text", DefaultSetter.getInstance ());

Of course, if we could not use DefaultSetter, the procedure would be slightly more complicated (still a one-line code), so it is usually a good idea to design XML attributes such that they directly correspond to Java variables/functions.

Often times, it is not necessary to specify DefaultSetter explicitly for all attributes it can handles. One can tell CookXml to use it by default:

tagLibrary.setSetter (null, null, DefaultSetter.getInstance ());

Step 4: Adders

Adders are used to add an object created by a child tag element to the object created by the parent tag element. In this case, we need to be able to add objects correspond to <menu> to object <menubar>, <menu> to <menu> and <menuitem> to <menu>.

CookXml provides DefaultAdder which can look for add (parameter) function of the parent object. It first looks up the add function that has the parameter class as the child object type. If that fails, then it tries to lookup other add functions that can handle the child object. This behavior is quite similar to that of Java compiler.

In this case, both JMenuBar and JMenu classes have corresponding add functions which can be found by DefaultAdder. So we will use it.

tagLibrary.setAdder ("menubar", DefaultAdder.getInstance ());
tagLibrary.setAdder ("menu", DefaultAdder.getInstance ());

Again, we can avoid the repetive specification by telling CookXml to use DefaultAdder as default.

tagLibrary.setAdder (null, DefaultAdder.getInstance ());

At this point, we have finished contructing the tag library needed for CookXml.

Step 5: Testing

To create a new instance of CookXml object, one need a DocumentBuilder for parsing XML documents and a tag library. The third parameters tells CookXml how to lookup certain variables, which will be explained in other tutorials.

JMenuBar menuBar;
try
{
	// the DocumentBuilder used to parse the XML Document.
	// This document builder does not read namespace information at all.
	DocumentBuilder builder = DocumentBuilderFactory.newInstance ().newDocumentBuilder ();
	CookXml cookXml = new CookXml (builder, s_tagLibrary, (Object)null);
	menuBar = (JMenuBar)cookXml.xmlDecode ("menubar1.xml");
}
catch (Exception ex)
{
	ex.printStackTrace ();
	return;
}

Resources

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

Valid XHTML 1.0! Valid CSS!