com.jgoodies.binding.adapter
Class BasicComponentFactory

java.lang.Object
  extended by com.jgoodies.binding.adapter.BasicComponentFactory

public class BasicComponentFactory
extends java.lang.Object

Consists only of static methods that create and vend frequently used Swing components that are then bound to a given ValueModel. This class is one of two helper classes that help you establish a binding: 1) the Bindings class binds components that have been created before; it wraps ValueModels with the adapters from package com.jgoodies.binding.adapter. 2) this BasicComponentFactory creates Swing components that are then tied to ValueModels using the the different #bind methods in the Bindings class.

If you have an existing factory that vends Swing components, you can use Bindings to bind them to ValueModels. If you don't have such a factory, you can use this BasicComponentFactory to create and bind Swing components.

This class is intended to be used or extended by custom ComponentFactory classes. Such a factory can create a broader variety of component types, may use different default configurations, and can use your favorite Formatters, FormatterFactories, etc.

Version:
$Revision: 1.16 $
Author:
Karsten Lentzsch
See Also:
ValueModel, Bindings

Constructor Summary
protected BasicComponentFactory()
           
 
Method Summary
static javax.swing.JCheckBox createCheckBox(ValueModel valueModel, java.lang.String text)
          Creates and returns a check box with the specified text label that is bound to the given ValueModel.
static javax.swing.JColorChooser createColorChooser(ValueModel valueModel)
          Creates and returns a JColorChooser that has the color selection bound to the given ValueModel.
static javax.swing.JColorChooser createColorChooser(ValueModel valueModel, java.awt.Color defaultColor)
          Creates and returns a JColorChooser that has the color selection bound to the given ValueModel.
static
<E> javax.swing.JComboBox
createComboBox(SelectionInList<E> selectionInList)
          Creates and returns a non-editable JComboBox that is bound to the given SelectionInList.
static
<E> javax.swing.JComboBox
createComboBox(SelectionInList<E> selectionInList, javax.swing.ListCellRenderer cellRenderer)
          Creates and returns a non-editable JComboBox that is bound to the given SelectionInList using the given cell renderer.
static javax.swing.JFormattedTextField createDateField(ValueModel valueModel)
          Creates and returns a formatted text field that is bound to the Date value of the given ValueModel.
static javax.swing.JFormattedTextField createFormattedTextField(ValueModel valueModel, java.text.Format format)
          Creates and returns a formatted text field that binds its value to the given model and converts Strings to values using the given Format.
static javax.swing.JFormattedTextField createFormattedTextField(ValueModel valueModel, javax.swing.JFormattedTextField.AbstractFormatter formatter)
          Creates and returns a formatted text field that binds its value to the given model and converts Strings to values using the given Formatter.
static javax.swing.JFormattedTextField createFormattedTextField(ValueModel valueModel, javax.swing.JFormattedTextField.AbstractFormatterFactory formatterFactory)
          Creates and returns a formatted text field that binds its value to the given model and converts Strings to values using Formatters provided by the given AbstractFormatterFactory.
static javax.swing.JFormattedTextField createFormattedTextField(ValueModel valueModel, java.lang.String mask)
          Creates and returns a formatted text field that binds its value to the given model and converts Strings to values using a MaskFormatter that is based on the given mask.
static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel)
          Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel.
static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel, int emptyNumber)
          Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel.
static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel, java.text.NumberFormat numberFormat)
          Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel.
static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel, java.text.NumberFormat numberFormat, int emptyNumber)
          Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel.
static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel, java.text.NumberFormat numberFormat, java.lang.Integer emptyNumber)
          Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel.
static javax.swing.JLabel createLabel(ValueModel valueModel)
          Creates and returns a text label that is bound to the given ValueModel.
static javax.swing.JLabel createLabel(ValueModel valueModel, java.text.Format format)
          Creates and returns a text label that is bound to the given ValueModel that is wrapped by a StringConverter.
static
<E> javax.swing.JList
createList(SelectionInList<E> selectionInList)
          Creates and returns a JList for the given SelectionInList.
static
<E> javax.swing.JList
createList(SelectionInList<E> selectionInList, javax.swing.ListCellRenderer cellRenderer)
          Creates and returns a JList for the given SelectionInList using the specified optional ListCellRenderer to render cells.
static javax.swing.JFormattedTextField createLongField(ValueModel valueModel)
          Creates and returns a formatted text field that is bound to the Long value of the given ValueModel.
static javax.swing.JFormattedTextField createLongField(ValueModel valueModel, long emptyNumber)
          Creates and returns a formatted text field that is bound to the Long value of the given ValueModel.
static javax.swing.JFormattedTextField createLongField(ValueModel valueModel, java.text.NumberFormat numberFormat)
          Creates and returns a formatted text field that is bound to the Long value of the given ValueModel.
static javax.swing.JFormattedTextField createLongField(ValueModel valueModel, java.text.NumberFormat numberFormat, long emptyNumber)
          Creates and returns a formatted text field that is bound to the Long value of the given ValueModel.
static javax.swing.JFormattedTextField createLongField(ValueModel valueModel, java.text.NumberFormat numberFormat, java.lang.Long emptyNumber)
          Creates and returns a formatted text field that is bound to the Long value of the given ValueModel.
static javax.swing.JPasswordField createPasswordField(ValueModel valueModel)
          Creates and returns a JPasswordField with the content bound to the given ValueModel.
static javax.swing.JPasswordField createPasswordField(ValueModel valueModel, boolean commitOnFocusLost)
          Creates and returns a JPasswordField with the content bound to the given ValueModel.
static javax.swing.JRadioButton createRadioButton(ValueModel model, java.lang.Object choice, java.lang.String text)
          Creates and returns a radio button with the specified text label that is bound to the given ValueModel.
static javax.swing.JTextArea createTextArea(ValueModel valueModel)
          Creates and returns a text area with the content bound to the given ValueModel.
static javax.swing.JTextArea createTextArea(ValueModel valueModel, boolean commitOnFocusLost)
          Creates and returns a text area with the content bound to the given ValueModel.
static javax.swing.JTextField createTextField(ValueModel valueModel)
          Creates and returns a text field with the content bound to the given ValueModel.
static javax.swing.JTextField createTextField(ValueModel valueModel, boolean commitOnFocusLost)
          Creates and returns a text field with the content bound to the given ValueModel.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

BasicComponentFactory

protected BasicComponentFactory()
Method Detail

createCheckBox

public static javax.swing.JCheckBox createCheckBox(ValueModel valueModel,
                                                   java.lang.String text)
Creates and returns a check box with the specified text label that is bound to the given ValueModel. The check box is selected if and only if the model's value equals Boolean.TRUE.

The model is converted to the required ToggleButtonModel using a ToggleButtonAdapter.

Parameters:
valueModel - the model that provides a Boolean value
text - the check boxes' text label
Returns:
a check box with the specified text bound to the given model, selected if the model's value equals Boolean.TRUE
Throws:
java.lang.NullPointerException - if the valueModel is null

createColorChooser

public static javax.swing.JColorChooser createColorChooser(ValueModel valueModel)
Creates and returns a JColorChooser that has the color selection bound to the given ValueModel. The ValueModel must be of type Color and must allow read-access to its value, and the initial value must not be null.

It is strongly recommended (though not required) that the underlying ValueModel provides only non-null values. This is so because the ColorSelectionModel behavior is undefined for null values and it may have unpredictable results. To avoid these problems, you may create the ColorChooser with a default color using createColorChooser(ValueModel, Color).

Parameters:
valueModel - a Color-typed ValueModel
Returns:
a color chooser with the selected color bound to the given model
Throws:
java.lang.NullPointerException - if the valueModel is null, or if its initial value is null
Since:
1.0.3
See Also:
createColorChooser(ValueModel, Color)

createColorChooser

public static javax.swing.JColorChooser createColorChooser(ValueModel valueModel,
                                                           java.awt.Color defaultColor)
Creates and returns a JColorChooser that has the color selection bound to the given ValueModel. The ValueModel must be of type Color and must allow read-access to its value. If the valueModel returns null, the given default color is used instead. This avoids problems with the ColorSelectionModel that may have unpredictable result for null values.

Parameters:
valueModel - a Color-typed ValueModel
defaultColor - the color used if the valueModel returns null
Returns:
a color chooser with the selected color bound to the given model
Throws:
java.lang.NullPointerException - if the valueModel or the default color is null,
Since:
1.1

createComboBox

public static <E> javax.swing.JComboBox createComboBox(SelectionInList<E> selectionInList)
Creates and returns a non-editable JComboBox that is bound to the given SelectionInList. The SelectionInList's ListModel is the list data provider and the selection index holder is used for the combo box model's selected item.

If the selectionInList's selection holder is a ComponentValueModel it is synchronized with the visible and enabled state of the returned combo box.

There are a couple of other possibilities to bind a JComboBox. See the constructors and the class comment of the ComboBoxAdapter.

Type Parameters:
E - the type of the combo box items and the selection
Parameters:
selectionInList - provides the list and selection
Returns:
a non-editable JComboBox that is bound to the SelectionInList
Throws:
java.lang.NullPointerException - if the selectionInList is null
Since:
1.0.1
See Also:
ComboBoxAdapter

createComboBox

public static <E> javax.swing.JComboBox createComboBox(SelectionInList<E> selectionInList,
                                                       javax.swing.ListCellRenderer cellRenderer)
Creates and returns a non-editable JComboBox that is bound to the given SelectionInList using the given cell renderer. The SelectionInList provides the list data and the selection index holder is used for the combo box model's selected item.

If the selectionInList's selection holder is a ComponentValueModel it is synchronized with the visible and enabled state of the returned combo box.

There are a couple of other possibilities to bind a JComboBox. See the constructors and the class comment of the ComboBoxAdapter.

Type Parameters:
E - the type of the combo box items and the selection
Parameters:
selectionInList - provides the list and selection
cellRenderer - an optional ListCellRenderer, can be null
Returns:
a non-editable JComboBox that is bound to the SelectionInList and uses the given renderer - if non-null
Throws:
java.lang.NullPointerException - if the selectionInList is null
Since:
1.0.1
See Also:
ComboBoxAdapter

createDateField

public static javax.swing.JFormattedTextField createDateField(ValueModel valueModel)
Creates and returns a formatted text field that is bound to the Date value of the given ValueModel. The JFormattedTextField is configured with an AbstractFormatter that uses two different DateFormats to edit and display the Date. A SHORT DateFormat with strict checking is used to edit (parse) a date; the DateFormatter's default DateFormat is used to display (format) a date. In both cases null Dates are mapped to the empty String.

Parameters:
valueModel - the model that holds the value to be edited
Returns:
a formatted text field for Date instances that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null

createFormattedTextField

public static javax.swing.JFormattedTextField createFormattedTextField(ValueModel valueModel,
                                                                       java.text.Format format)
Creates and returns a formatted text field that binds its value to the given model and converts Strings to values using the given Format.

Parameters:
valueModel - the model that provides the value
format - the Format used to convert values into a text representation and vice versa via #format and #parse
Returns:
a formatted text field that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null

createFormattedTextField

public static javax.swing.JFormattedTextField createFormattedTextField(ValueModel valueModel,
                                                                       javax.swing.JFormattedTextField.AbstractFormatter formatter)
Creates and returns a formatted text field that binds its value to the given model and converts Strings to values using the given Formatter.

Parameters:
valueModel - the model that provides the value
formatter - the Formatter used to convert values to a text representation and vice versa via #valueToString and #stringToValue
Returns:
a formatted text field that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null

createFormattedTextField

public static javax.swing.JFormattedTextField createFormattedTextField(ValueModel valueModel,
                                                                       javax.swing.JFormattedTextField.AbstractFormatterFactory formatterFactory)
Creates and returns a formatted text field that binds its value to the given model and converts Strings to values using Formatters provided by the given AbstractFormatterFactory.

Parameters:
valueModel - the model that provides the value
formatterFactory - provides formatters for different field states that in turn are used to convert values to a text representation and vice versa via #valueToString and #stringToValue
Returns:
a formatted text field that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null

createFormattedTextField

public static javax.swing.JFormattedTextField createFormattedTextField(ValueModel valueModel,
                                                                       java.lang.String mask)
Creates and returns a formatted text field that binds its value to the given model and converts Strings to values using a MaskFormatter that is based on the given mask.

Parameters:
valueModel - the model that provides the value
mask - the mask pattern used to create an instance of MaskFormatter that in turn converts values to Strings and vice versa
Returns:
a bound formatted text field using a MaskFormatter
Throws:
java.lang.NullPointerException - if the valueModel is null
java.lang.IllegalArgumentException - if the mask is invalid

createIntegerField

public static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel)
Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel. Empty strings are converted to null and vice versa.

The Format used to convert numbers to strings and vice versa is NumberFormat.getIntegerInstance().

Parameters:
valueModel - the model that holds the value to be edited
Returns:
a formatted text field for Integer instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the valueModel is null

createIntegerField

public static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel,
                                                                 int emptyNumber)
Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel. Empty strings are converted to the specified empty number.

The Format used to convert numbers to strings and vice versa is NumberFormat.getIntegerInstance().

Parameters:
valueModel - the model that holds the value to be edited
emptyNumber - an Integer that represents the empty string
Returns:
a formatted text field for Integer instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the valueModel is null

createIntegerField

public static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel,
                                                                 java.text.NumberFormat numberFormat)
Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel. Empty strings are converted to null and vice versa.

Parameters:
valueModel - the model that holds the value to be edited
numberFormat - used to convert numbers to strings and vice versa
Returns:
a formatted text field for Integer instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the valueModel is null

createIntegerField

public static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel,
                                                                 java.text.NumberFormat numberFormat,
                                                                 int emptyNumber)
Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel. Empty strings are converted to the specified empty number.

Parameters:
valueModel - the model that holds the value to be edited
numberFormat - used to convert numbers to strings and vice versa
emptyNumber - an Integer that represents the empty string
Returns:
a formatted text field for Integer instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the valueModel is null

createIntegerField

public static javax.swing.JFormattedTextField createIntegerField(ValueModel valueModel,
                                                                 java.text.NumberFormat numberFormat,
                                                                 java.lang.Integer emptyNumber)
Creates and returns a formatted text field that is bound to the Integer value of the given ValueModel. Empty strings are converted to the specified empty number.

Parameters:
valueModel - the model that holds the value to be edited
numberFormat - used to convert numbers to strings and vice versa
emptyNumber - an Integer that represents the empty string
Returns:
a formatted text field for Integer instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the valueModel is null

createLongField

public static javax.swing.JFormattedTextField createLongField(ValueModel valueModel)
Creates and returns a formatted text field that is bound to the Long value of the given ValueModel. Empty strings are converted to null and vice versa.

The Format used to convert numbers to strings and vice versa is NumberFormat.getIntegerInstance().

Parameters:
valueModel - the model that holds the value to be edited
Returns:
a formatted text field for Long instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the model is null

createLongField

public static javax.swing.JFormattedTextField createLongField(ValueModel valueModel,
                                                              long emptyNumber)
Creates and returns a formatted text field that is bound to the Long value of the given ValueModel. Empty strings are converted to the specified empty number.

The Format used to convert numbers to strings and vice versa is NumberFormat.getIntegerInstance().

Parameters:
valueModel - the model that holds the value to be edited
emptyNumber - a Long that represents the empty string
Returns:
a formatted text field for Long instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the model is null

createLongField

public static javax.swing.JFormattedTextField createLongField(ValueModel valueModel,
                                                              java.text.NumberFormat numberFormat)
Creates and returns a formatted text field that is bound to the Long value of the given ValueModel. Empty strings are converted to null and vice versa.

Parameters:
valueModel - the model that holds the value to be edited
numberFormat - used to convert numbers to strings and vice versa
Returns:
a formatted text field for Long instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the model is null

createLongField

public static javax.swing.JFormattedTextField createLongField(ValueModel valueModel,
                                                              java.text.NumberFormat numberFormat,
                                                              long emptyNumber)
Creates and returns a formatted text field that is bound to the Long value of the given ValueModel. Empty strings are converted to the specified empty number.

Parameters:
valueModel - the model that holds the value to be edited
numberFormat - used to convert numbers to strings and vice versa
emptyNumber - a Long that represents the empty string
Returns:
a formatted text field for Long instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the model is null

createLongField

public static javax.swing.JFormattedTextField createLongField(ValueModel valueModel,
                                                              java.text.NumberFormat numberFormat,
                                                              java.lang.Long emptyNumber)
Creates and returns a formatted text field that is bound to the Long value of the given ValueModel. Empty strings are converted to the specified empty number.

Parameters:
valueModel - the model that holds the value to be edited
numberFormat - used to convert numbers to strings and vice versa
emptyNumber - a Long that represents the empty string
Returns:
a formatted text field for Long instances that is bound to the specified valueModel
Throws:
java.lang.NullPointerException - if the model is null

createLabel

public static javax.swing.JLabel createLabel(ValueModel valueModel)
Creates and returns a text label that is bound to the given ValueModel.

Parameters:
valueModel - the model that provides the value
Returns:
a text label that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null

createLabel

public static javax.swing.JLabel createLabel(ValueModel valueModel,
                                             java.text.Format format)
Creates and returns a text label that is bound to the given ValueModel that is wrapped by a StringConverter. The conversion to Strings uses the specified Format.

Parameters:
valueModel - the model that provides the value
format - the format used to create the StringConverter
Returns:
a text label that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null
See Also:
ConverterFactory

createList

public static <E> javax.swing.JList createList(SelectionInList<E> selectionInList)
Creates and returns a JList for the given SelectionInList.

If the selectionInList's selection holder is a ComponentValueModel it is synchronized with the visible and enabled state of the returned list.

Type Parameters:
E - the type of the list items and the selection
Parameters:
selectionInList - provides the list and selection
Returns:
a JList bound to the given SelectionInList
Throws:
java.lang.NullPointerException - if selectionInList is null

createList

public static <E> javax.swing.JList createList(SelectionInList<E> selectionInList,
                                               javax.swing.ListCellRenderer cellRenderer)
Creates and returns a JList for the given SelectionInList using the specified optional ListCellRenderer to render cells.

If the selectionInList's selection holder is a ComponentValueModel it is synchronized with the visible and enabled state of the returned list.

Type Parameters:
E - the type of the list items and the selection
Parameters:
selectionInList - provides the list and selection
cellRenderer - an optional ListCellRenderer, can be null
Returns:
a JList bound to the given SelectionInList
Throws:
java.lang.NullPointerException - if selectionInList is null

createPasswordField

public static javax.swing.JPasswordField createPasswordField(ValueModel valueModel)
Creates and returns a JPasswordField with the content bound to the given ValueModel. Text changes are committed to the model on focus lost.

Security Note: The binding created by this method uses Strings as values of the given ValueModel. The String-typed passwords could potentially be observed in a security fraud. For stronger security it is recommended to request a character array from the JPasswordField and clear the array after use by setting each character to zero. Method JPasswordField.getPassword() return's the field's password as a character array.

Parameters:
valueModel - the model that provides the value
Returns:
a text field that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null
See Also:
createPasswordField(ValueModel, boolean), JPasswordField.getPassword()

createPasswordField

public static javax.swing.JPasswordField createPasswordField(ValueModel valueModel,
                                                             boolean commitOnFocusLost)
Creates and returns a JPasswordField with the content bound to the given ValueModel. Text changes can be committed to the model on focus lost or on every character typed.

Security Note: The binding created by this method uses Strings as values of the given ValueModel. The String-typed passwords could potentially be observed in a security fraud. For stronger security it is recommended to request a character array from the JPasswordField and clear the array after use by setting each character to zero. Method JPasswordField.getPassword() return's the field's password as a character array.

Parameters:
valueModel - the model that provides the value
commitOnFocusLost - true to commit text changes on focus lost, false to commit text changes on every character typed
Returns:
a text field that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null
See Also:
createPasswordField(ValueModel), JPasswordField.getPassword()

createRadioButton

public static javax.swing.JRadioButton createRadioButton(ValueModel model,
                                                         java.lang.Object choice,
                                                         java.lang.String text)
Creates and returns a radio button with the specified text label that is bound to the given ValueModel. The radio button is selected if and only if the model's value equals the specified choice.

The model is converted to the required ToggleButton using a RadioButtonAdapter.

Parameters:
model - the model that provides the current choice
choice - this button's value
text - the radio buttons' text label
Returns:
a radio button with the specified text bound to the given model, selected if the model's value equals the specified choice
Throws:
java.lang.NullPointerException - if the valueModel is null

createTextArea

public static javax.swing.JTextArea createTextArea(ValueModel valueModel)
Creates and returns a text area with the content bound to the given ValueModel. Text changes are committed to the model on focus lost.

Parameters:
valueModel - the model that provides the value
Returns:
a text area that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null
See Also:
createTextArea(ValueModel, boolean)

createTextArea

public static javax.swing.JTextArea createTextArea(ValueModel valueModel,
                                                   boolean commitOnFocusLost)
Creates and returns a text area with the content bound to the given ValueModel. Text changes can be committed to the model on focus lost or on every character typed.

Parameters:
valueModel - the model that provides the text value
commitOnFocusLost - true to commit text changes on focus lost, false to commit text changes on every character typed
Returns:
a text area that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null
See Also:
createTextArea(ValueModel)

createTextField

public static javax.swing.JTextField createTextField(ValueModel valueModel)
Creates and returns a text field with the content bound to the given ValueModel. Text changes are committed to the model on focus lost.

Parameters:
valueModel - the model that provides the value
Returns:
a text field that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null
See Also:
createTextField(ValueModel, boolean)

createTextField

public static javax.swing.JTextField createTextField(ValueModel valueModel,
                                                     boolean commitOnFocusLost)
Creates and returns a text field with the content bound to the given ValueModel. Text changes can be committed to the model on focus lost or on every character typed.

Parameters:
valueModel - the model that provides the text value
commitOnFocusLost - true to commit text changes on focus lost, false to commit text changes on every character typed
Returns:
a text field that is bound to the given value model
Throws:
java.lang.NullPointerException - if the valueModel is null
See Also:
createTextField(ValueModel)


Copyright © 2002-2008 JGoodies Karsten Lentzsch. All Rights Reserved.