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
|