Tutorial 4: Creators and Adders


 

 

Support This Project

 

stats counter

 

Logo SourceForge.net Logo IntelliJ IDEA

Introduction

We have dealt with setters and converters in the previous tutorials. This tutorial teaches how to use Creator and Adder in a tag library.

For the illustration purpose, assuming that we want to be able to obtain icons from UIManager (using UIManager.getIcon (String key)) function, and be able to add it to a menu or menu item. Assume the attribute "ui" specifies the UI resource key.

<?xml version="1.0"?>
<menubar>
	<menu text="File">
		<menu text="Open">
			<menuitem text="XML">
				<icon ui="OptionPane.informationIcon"/>
			</menuitem>
			<menuitem text="Java"/>
		</menu>
		<menuitem text="Exit" accelerator="control Q"/>
	</menu>
	<menu text="Edit">
		<menuitem text="Cut" horizontalalignment="center"/>
		<menuitem text="Copy" horizontalalignment="right"/>
		<menuitem text="Paste" horizontalalignment="left"/>
	</menu>
	<menu text="Help">
		<menuitem text="About" accelerator="F1"/>
	</menu>
</menubar>

To do as described above, there need to be two steps. First is to write a Creator that can obtain the icon from UIManager, and second is to write an Adder so that the icon can be added to the menu item. Note that JMenuItem does not have an add function that adds a icon, so we cannot expect the DefaultAdder to work for us by default. JMenuItem does have a function call setIcon, which we would write an adder to call it when <icon> is a child of <menuitem> tag.

Step 1: Writing a Creator

A Creator is used to create objects corresponding to an XML tag. In this case, we need to write a Creator that can give us the Icon object.

The complication arises when we need to obtain the icon key from the attribute "ui" before we can actually create the icon object. The DefaultCreator thus cannot do the job for us. We need to write a custom creator. In our case, we use the parameter elm to find out the value specified for "ui" and use that key to find the needed icon from UIManager. For simplicity, I omitted code that does error checking.

import javax.swing.*;

import org.w3c.dom.Element;

import cookxml.core.DecodeEngine;
import cookxml.core.exception.CookXmlException;
import cookxml.core.exception.CreatorException;
import cookxml.core.interfaces.Creator;

public class IconCreator implements Creator
{
	public Object create (String parentNS, String parentTag, Element elm, Object parentObj, DecodeEngine decodeEngine) throws CreatorException
	{
		// look ahead to see if "ui" attribute is specified.
		String iconKey = elm.getAttribute ("ui");
		return UIManager.getIcon (iconKey);
	}

	public Object editFinished (String parentNS, String parentTag, Element elm, Object parentObj, Object obj, DecodeEngine decodeEngine) throws CookXmlException
	{
		// usually if one is not doing anything special here, then just need to
		// return obj.
		return obj;
	}
}

Step 2: Installing the Creator

Installation of the custom creator is just like in tutorial 1.

tagLibrary.setCreator ("icon", new IconCreator ());

Step 3: Creating an Adder

Now the remaining question is how to add the icon object to the menu item. We can do so by creating an Adder just for "menuitem" tag. Note that the return value of an Adder indicates if the Adder can handle the parent/child combination, while exception thrown by the Adder is used to indicate errors.

import javax.swing.*;

import cookxml.core.interfaces.Adder;
import cookxml.core.DecodeEngine;
import cookxml.core.exception.AdderException;

public class MenuItemAdder implements Adder
{
	public boolean add (String parentNS, String parentTag, Object parent, Object child, DecodeEngine decodeEngine) throws AdderException
	{
		if (!(parent instanceof JMenuItem) ||
			!(child instanceof Icon))
			return false;

		((JMenuItem)parent).setIcon ((Icon)child);
		return true;
	}
}

Step 4: Installing the Adder

This step is just like what we did in tutorial 1. Each tag can only have one adder, but you can use CompoundAdder to chain several adders into one. The adder that cannot handle a particular addition should return false, so the next adder in turn could check it can do the job.

tagLibrary.setAdder ("menuitem", new MenuItemAdder ());

Resources

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

Valid XHTML 1.0! Valid CSS!