Abstractics XmlPanel
A flexible Java Swing Runtime Layout Manager Current Version: 1.1

The Component Factory

How Does the XmlPanel Know What Component to Create?

That's a good question. As the XML is parsed by the XmlPanel it has to determine what type of component to create. You may have noticed in previous examples the type attribute in the cell tags. The type determines the component to be created. We've already used examples like "button", and "text", but the flexibility goes far deeper than that.

The XmlPanel uses an object called the ComponentFactory for all of its component creation. The factory's job is to look at a given XML tag and determine what kind of component (a subclass of java.awt.Component) to create.

The ComponentFactory holds a collection of ComponentCreator objects. ComponentCreator is an interface that can be implemented by anything. The createComponent() method is called by the ComponentFactory when a Component is needed. See the ComponentCreator and ComponentFactory JavaDoc for detailed information.

When the ComponentFactory is asked to create a component for a given XML tag, it follows the following steps to determine what ComponentCreator to use:

  • If the name of the tag is panel then the creator for the XmlPanel is used. This is to handle the initial <panel> tag in the XML.
  • If the tag has a child <row> tag then the creator for the XmlPanel is used.
  • If the type is null, then the creator for the type "label" is used.
  • If the type is not null, then the type is used to find the creator with the matching type in the factory (case-insensitive).
  • If all of the previous cases have failed, then the type is attempted to be instantiated as a fully qualified class name (i.e. type="javax.swing.JTextField" will work). If the instantiation cannot occur, or results in an object that is not a subclass of java.awt.Component, then a RuntimeException is thrown.

Pre-Loaded ComponentCreators

When the ComponentFactory is constructed it is pre-loaded with some ComponentCreators for common Swing components. The following are pre-loaded:

  • label - creates javax.swing.JLabel
  • text - creates javax.swing.JTextField
  • button - creates javax.swing.JButton
  • textarea - creates javax.swing.JTextArea
  • radio - creates javax.swing.JRadioButton
  • checkbox - creates javax.swing.JCheckBox
  • scrollpane - creates javax.swing.JScrollPane -- This is a special ComponentCreator. It expects a child <component> tag to determine what component to put in the scroll pane. See the JScrollPaneCreator JavaDoc for more info.

Installing/Overriding ComponentCreators

To create your own ComponentCreator, create a class that implements the ComponentCreator interface. Additional ComponentCreators can be added to the singleton ComponentFactory at any time by calling the addXmlPanelComponentCreator() method. The type names of creators are not case-sensitive. If a new creator is installed with the same type name as an existing creator, then the existing creator will be overridden.

The creators need to be in place before any XmlPanels are created in order for the components to be found.

AbstractComponentCreator and Setting Properties via Reflection

AbstractComponentCreator is an implementation of ComponentCreator that will usually be the basis for new creators. What does it do different? After the component is created, it uses reflection to set any properties on the component that match attributes in the XML tag.

Any attributes on the XML tag that match setter methods on the resulting component (using bean style naming conventions) will be used to call the setter method. For example, buttons have a method on them called setMnemonic(char). If you wanted to create a cell that has a Save button in it, and you want the mnemonic to be the 'S' character, then the following would work:


<cell type="button" mnemonic="s">Save</cell>
	

Notice that the text of the tag is "Save". If the component that is created has a setText() method, then the text of the tag is used to call that method.

But it doesn't stop with simple numbers and strings. Complex setters can also be called for parameters such as fonts, colors, sizes, and borders. StringToObject is a utilty class that is used to translate a string into Java object types.

Next: StringToObject Utility