All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.cuf.ui.builder.VisualBuilderDelegate Maven / Gradle / Ivy

The newest version!
package net.sf.cuf.ui.builder;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Dimension;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.JViewport;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.text.Document;
import javax.swing.text.MaskFormatter;
import javax.swing.text.DateFormatter;
import javax.swing.text.NumberFormatter;

import org.jdom2.Attribute;
import org.jdom2.DataConversionException;
import org.jdom2.Element;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.factories.Borders;
import com.jgoodies.forms.layout.FormLayout;
import net.sf.cuf.ui.DispatcherAction;
import net.sf.cuf.ui.FlexibleGridLayout;
import net.sf.cuf.ui.SwingDecoratorFunctionality;
import net.sf.cuf.ui.TableLayout2;
import net.sf.cuf.ui.TitledSeparator;

/**
 * The VisualBuilderDelegate class handles the "visual" entry of a xml2swing XML
 * description.
 */
class VisualBuilderDelegate implements SwingXMLBuilder.BuilderDelegate
{
    // null, only set when inside a build method
    private SwingXMLBuilder mBuilder;

     // map for the JGoodie Forms empty borders, key= name, value= border object
    private static Map     sEmptyBorders;

    static
    {
        sEmptyBorders= new HashMap();
        sEmptyBorders.put("dlu2",           Borders.DLU2);
        sEmptyBorders.put("dlu4",           Borders.DLU4);
        sEmptyBorders.put("dlu7",           Borders.DLU7);
        sEmptyBorders.put("dlu14",          Borders.DLU14);
        sEmptyBorders.put("buttonbar_gap",  Borders.BUTTON_BAR_PAD);
        sEmptyBorders.put("dialog",         Borders.DIALOG);
        sEmptyBorders.put("tabbed_dialog",  Borders.TABBED_DIALOG);
    }

    /**
     * Build the specific part of the delegate.
     *
     * @param pBuilder
     *            the builder that controls the creation process
     * @param pElement
     *            the JDOM element the delegate should handle ("visual" in our
     *            case)
     */
    public void build(SwingXMLBuilder pBuilder, Element pElement)
    {
        mBuilder = pBuilder;
        try
        {
            List topLevelChildren = pElement.getChildren();
            for (Element topLevel : topLevelChildren)
            {
                if (isWidgetElement(topLevel))
                {
                    addChildren(null, topLevel);
                }
                else
                {
                    // silently ignore unknown stuff
                }
            }
        }
        finally
        {
            mBuilder = null;
        }
    }

    /**
     * This method does recursivly create the widgets.
     *
     * @param pParentWidget
     *            null or the parent widget
     * @param pXMLCurrent
     *            the child widget as a XML element
     * @throws IllegalArgumentException
     *             if problems are found
     */
    public void addChildren(Container pParentWidget, Element pXMLCurrent)
            throws IllegalArgumentException
    {
        List childElements      = pXMLCurrent.getChildren();
        List childWidgetElements= new ArrayList<>();
        WidgetElement currentWidget;

        // create ourself
        currentWidget = createWidget(pParentWidget, pXMLCurrent);

        // handle our child widgets and our attributes
        for (Element childElement : childElements)
        {
            if (isWidgetElement(childElement))
            {
                // create a child (deferred, to decorate the current element first)
                childWidgetElements.add(childElement);
            }
            else if (isWidgetDecoration(childElement))
            {
                // decorate ourself
                decorateWidget(currentWidget.getWidget(), childElement);
            }
            else
            {
                // silently ignore unknown stuff
            }
        }

        // decorate ourself with entries from a resource bundle
        SwingDecoratorFunctionality decorator = mBuilder.getSwingDecorator();
        if ( decorator != null )
        {
            Object widget = currentWidget.getWidget();
            String name = (String)mBuilder.getVisualToName().get(widget);
            if ( name != null && widget instanceof Component )
            {
                // general case is handled by the SwingDecorator
                decorator.initialize((Component)widget, name);
                // special case TitledBorder (see also decorateWidget, widgetDecorationName.equals(SwingXMLBuilder.TITLE_ELEMENT))
                if ( widget instanceof JComponent )
                {
                    String title = decorator.getTitle(name);
                    if ( title != null )
                    {
                        ((JComponent)widget).setBorder(new TitledBorder(title));
                    }
                }
            }
        }

        // create our childs
        for (Element childElement : childWidgetElements)
        {
            addChildren(currentWidget.getComponent(), childElement);
        }

        // add ourself to our parent
        if (currentWidget.isPseudoWidget())
        {
            PseudoWidget pseudoWidget = currentWidget.getPseudoWidget();
            pseudoWidget.addToParent(pParentWidget);
        }
        else if (pParentWidget != null)
        {
            Component currentComponent = currentWidget.getComponent();
            // special case for toolbar item build from an action or from a separator
            if (currentComponent == null)
            {
                // nothing to do, the item was added in the create method
            }
            // special case for JSplitPane
            else if (pParentWidget instanceof JSplitPane)
            {
                // if there is no left component, we are the "left" one,
                // otherwise we are the right one
                JSplitPane splitPane = (JSplitPane) pParentWidget;
                if (splitPane.getLeftComponent() == null)
                {
                    splitPane.setLeftComponent(currentComponent);
                }
                else
                {
                    splitPane.setRightComponent(currentComponent);
                }
            }
            // special case for JScrollPane
            else if (pParentWidget instanceof JScrollPane)
            {
                ((JScrollPane) pParentWidget).setViewportView(currentComponent);
            }
            // special case for JTabbedPane
            else if (pParentWidget instanceof JTabbedPane)
            {
                JTabbedPane tabbedPane= (JTabbedPane) pParentWidget;
                Map         tabMapping= (Map) tabbedPane.getClientProperty(SwingXMLBuilder.TABMAPPING_PROPERTY);
                String      widgetName= currentComponent.getName();
                if ((tabMapping != null) && tabMapping.containsKey(widgetName))
                {
                    Object[] mapValue = (Object[]) tabMapping.get(widgetName);
                    tabbedPane.addTab((String) mapValue[0], (Icon) mapValue[1],
                                      currentComponent, (String) mapValue[2]);
                    // remove this mapping, and remove map if this was the
                    // last entry
                    tabMapping.remove(widgetName);
                    if (tabMapping.size() == 0)
                    {
                        tabbedPane.putClientProperty(SwingXMLBuilder.TABMAPPING_PROPERTY, null);
                    }
                }
                else
                {
                    // silently ignore non-mapped childs
                }
            }
            // special case for JFrame
            else if (pParentWidget instanceof JFrame)
            {
                JFrame frame = (JFrame) pParentWidget;
                if (currentComponent instanceof JMenuBar)
                {
                    frame.setJMenuBar((JMenuBar) currentComponent);
                }
                else if (currentComponent instanceof JToolBar)
                {
                    frame.getContentPane().add(currentComponent,
                            BorderLayout.NORTH);
                }
                else if (currentComponent instanceof JDialog)
                {
                    // nothing to do, already done in the createDialog method
                }
                else
                {
                    // currently we support only one panel per JFrame
                    frame.getContentPane().add(currentComponent);
                }
            }
            // special case for JDialog
            else if (pParentWidget instanceof JDialog)
            {
                ((JDialog) pParentWidget).getContentPane().add(currentComponent);
            }
            else
            {
                // special case if a builder is used
                DefaultFormBuilder builder= null;
                if (pParentWidget instanceof JPanel)
                {
                    JPanel panel=(JPanel)pParentWidget;
                    builder= (DefaultFormBuilder)panel.getClientProperty(SwingXMLBuilder.FORMBUILDER_PROPERTY);
                }
                Object constraint= currentWidget.getConstraint();
                if (constraint!=null)
                {
                    if (builder!=null)
                    {
                        if (!(constraint instanceof String))
                        {
                            throw SwingXMLBuilder.createException(
                                    "invalid constraint "+constraint+" for builder",
                                    pXMLCurrent);
                        }
                        builder.add(currentComponent, (String)constraint);
                    }
                    else
                    {
                        pParentWidget.add(currentComponent, constraint);
                    }
                }
                else
                {
                    if (builder!=null)
                    {
                        builder.append(currentComponent);
                    }
                    else
                    {
                        pParentWidget.add(currentComponent);
                    }
                }
            }
        } // end add ourself to our parent

        // notify the newly created widget that its creation was completed
        if (currentWidget.getComponent() != null)
        {
            // special case for JFrame and JDialog to add the default button
            Component component= currentWidget.getComponent();
            if ((component instanceof JFrame) || (component instanceof JDialog))
            {
                String defaultButton= pXMLCurrent.getAttributeValue(SwingXMLBuilder.DEFAULT_ATTRIBUTE);
                if (defaultButton!=null )
                {
                    if (!(mBuilder.get(defaultButton) instanceof JButton))
                    {
                          throw SwingXMLBuilder.createException("could not find default button " +
                                                                defaultButton, pXMLCurrent);
                    }
                    JButton button= (JButton) mBuilder.get(defaultButton);
                    if (component instanceof JFrame)
                        ((JFrame)component).getRootPane().setDefaultButton(button);
                    else
                        ((JDialog)component).getRootPane().setDefaultButton(button);
                }
            }
            mBuilder.getWidgetFactory().notifyWidgetComplete(
                    currentWidget.getComponent().getClass().getName(),
                    pXMLCurrent,
                    currentWidget.getComponent());
        }
    }

    /**
     * Tests if the given node is a widget decoration and not a ("new") widget.
     *
     * @param pElement
     *            node to test
     * @return true if the elment node is a widget description
     * @noinspection RedundantIfStatement
     */
    private static boolean isWidgetDecoration(Element pElement)
    {
        String widgetDecorationName = pElement.getName();
        if (widgetDecorationName.equals(SwingXMLBuilder.PROPERTY_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.TEXT_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.TITLE_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.MNEMONIC_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.ACCELERATOR_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.SHORTCUT_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.TOOLTIP_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.ICON_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.COMBOITEM_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.TABMAPPING_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.TABITEM_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.POPUPREF_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.LAYOUTMANAGER_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.CONSTRAINT_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.BORDER_ELEMENT))
            return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.MINSIZE_ELEMENT))
        	return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.MAXSIZE_ELEMENT))
        	return true;
        else if (widgetDecorationName.equals(SwingXMLBuilder.PREFSIZE_ELEMENT))
        	return true;
        else
            return false;
    }

    private FormLayout createFormLayout(Element pElement)
    {
        String columns= pElement.getChildTextNormalize(SwingXMLBuilder.COLUMNS_ELEMENT);
        String rows   = pElement.getChildTextNormalize(SwingXMLBuilder.ROWS_ELEMENT);
        if (rows == null)
        {
            rows = ""; // to support the builder better
        }
        FormLayout formLayout  = new FormLayout(columns, rows);
        String     columnGroups= pElement.getChildTextNormalize(SwingXMLBuilder.COLUMNGROUPS_ELEMENT);
        String     rowGroups   = pElement.getChildTextNormalize(SwingXMLBuilder.ROWGROUPS_ELEMENT);
        if (columnGroups != null)
        {
            formLayout.setColumnGroups(getGroups(columnGroups));
        }
        if (rowGroups != null)
        {
            formLayout.setRowGroups(getGroups(rowGroups));
        }
        return formLayout;
    }

    /**
     * Small helper to extract the groups for the FormLayout setColumnGroups()/
     * setRowGroups() calls.
     *
     * @param pGroups
     *            String describing the groups, ";" separates groups, ","
     *            separats single rows/columns
     * @return a array of int arrays matching pGroups
     */
    private int[][] getGroups(String pGroups)
    {
        int[][] groupsIndeces;
        StringTokenizer groups = new StringTokenizer(pGroups, ";");
        groupsIndeces = new int[groups.countTokens()][];
        for (int i = 0, n = groupsIndeces.length; i < n; i++)
        {
            StringTokenizer sameSize = new StringTokenizer(groups.nextToken(),
                    ",");
            groupsIndeces[i] = new int[sameSize.countTokens()];
            for (int j = 0, m = groupsIndeces[i].length; j < m; j++)
            {
                groupsIndeces[i][j] = Integer.parseInt(sameSize.nextToken());
            }
        }
        return groupsIndeces;
    }

    /**
     * Helper to add (recoursivly) a border to a component.
     *
     * @param pElement
     *            border element
     * @param pComponent
     *            component where we should add the border
     */
    private void addBorder(Element pElement, JComponent pComponent)
    {
        Border border = getBorder(pElement);

        if (border != null)
        {
            // handle inner borders
            Element childBorderElement = pElement.getChild(SwingXMLBuilder.BORDER_ELEMENT);
            if (childBorderElement != null)
            {
                addBorder(childBorderElement, pComponent);
            }
            // add our border on top of another inner border
            Border oldBorder = pComponent.getBorder();
            if (oldBorder != null)
            {
                border = BorderFactory.createCompoundBorder(border, oldBorder);
            }
            pComponent.setBorder(border);
        }
    }

    /**
     * Small helper to get the border of a Element.
     * @param pElement the border element, may be null
     * @return null or a border
     */
    static Border getBorder(Element pElement)
    {
        if (pElement==null)
        {
            return null;
        }

        // line | etched | bevel | empty | matte
        String type  = pElement.getAttributeValue(SwingXMLBuilder.TYPE_ATTRIBUTE);
        Border border= null;
        if (SwingXMLBuilder.LINE_ATTRIBUTE.equals(type))
        {
            Color color = getColor(pElement, 0);
            if (color != null)
            {
                int     thickness       = 1;
                Element thicknessElement= pElement.getChild(SwingXMLBuilder.THICKNESS_ELEMENT);
                if (thicknessElement != null)
                {
                    thickness = Integer.parseInt(thicknessElement.getTextTrim());
                }
                border = BorderFactory.createLineBorder(color, thickness);
            }
        }
        else if (SwingXMLBuilder.ETCHED_ATTRIBUTE.equals(type))
        {
            int    etchType= EtchedBorder.LOWERED;
            String sunken  = pElement.getAttributeValue(SwingXMLBuilder.SUNKEN_ATTRIBUTE);
            if (SwingXMLBuilder.SUNKEN_RAISED.equals(sunken))
            {
                etchType = EtchedBorder.RAISED;
            }
            Color highlight= getColor(pElement, 0);
            Color shadow   = getColor(pElement, 1);
            if ((highlight != null) && (shadow != null))
            {
                border = BorderFactory.createEtchedBorder(etchType, highlight, shadow);
            }
            else
            {
                border = BorderFactory.createEtchedBorder(etchType);
            }
        }
        else if (SwingXMLBuilder.BEVEL_ATTRIBUTE.equals(type))
        {
            int    bevelType= BevelBorder.LOWERED;
            String sunken   = pElement.getAttributeValue(SwingXMLBuilder.SUNKEN_ATTRIBUTE);
            if (SwingXMLBuilder.SUNKEN_RAISED.equals(sunken))
            {
                bevelType = BevelBorder.RAISED;
            }
            Color highlight= getColor(pElement, 0);
            Color shadow   = getColor(pElement, 1);
            if ((highlight != null) && (shadow != null))
            {
                border = BorderFactory.createBevelBorder(bevelType, highlight, shadow);
            }
            else
            {
                border = BorderFactory.createBevelBorder(bevelType);
            }
        }
        else if (SwingXMLBuilder.EMPTY_ATTRIBUTE.equals(type))
        {
            // check if we should build a JGoodies Forms EmptyBorder
            String forms= pElement.getChildTextTrim(SwingXMLBuilder.DLU_ELEMENT);
            if (forms!=null)
            {
                if (sEmptyBorders.containsKey(forms))
                {
                    border= (Border)sEmptyBorders.get(forms);
                }
                else
                {
                    try
                    {
                        border= Borders.createEmptyBorder(forms);
                    }
                    catch (IllegalArgumentException e)
                    {
                        throw SwingXMLBuilder.createException("could not create a JGoodies Forms EmptyBorder," +
                                                              " forms= "+forms, e, pElement);
                    }
                }
            }
            else
            {
                // normal empty border
                Insets insets= getInsets(pElement);
                border= BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right);
            }
        }
        else if (SwingXMLBuilder.MATTE_ATTRIBUTE.equals(type))
        {
            Insets insets= getInsets(pElement);
            Color  color = getColor(pElement, 0);
            if (color != null)
            {
                border = BorderFactory.createMatteBorder(insets.top, insets.left, insets.bottom, insets.right, color);
            }
        }

        return border;
    }

    /**
     * Get a color from a color element.
     * @param pElement the element the color is a child
     * @param pos the position of the color element
     * @return null or a color
     */
    static Color getColor(Element pElement, int pos)
    {
        Color color       = null;
        List colorChildren= pElement.getChildren(SwingXMLBuilder.COLOR_ELEMENT);
        if (pos < colorChildren.size())
        {
            color = getColor((Element) colorChildren.get(pos));
        }
        return color;
    }

    private static Color getColor(Element pColorElement)
    {
        Color  color;
        String r    = pColorElement.getAttributeValue("r");
        String g    = pColorElement.getAttributeValue("g");
        String b    = pColorElement.getAttributeValue("b");
        String alpha= pColorElement.getAttributeValue("a");
        if (alpha == null)
        {
            color = new Color(Integer.parseInt(r), Integer.parseInt(g), Integer.parseInt(b));
        }
        else
        {
            color = new Color(Integer.parseInt(r), Integer.parseInt(g), Integer.parseInt(b), Integer.parseInt(alpha));
        }
        return color;
    }

    /**
     * store the mapping information in the tabbed pane as a client property,
     * the ref attribute is used as a key, value is a Object[3] array of title,
     * icon and tooltip.
     *
     * @param pTabMapping where to store the information
     * @param pElement    the tabmapping element containing the mapping
     */
    private void storeTabMapInformation(Map pTabMapping, Element pElement)
    {
        List tabItems = pElement.getChildren(SwingXMLBuilder.TABITEM_ELEMENT);
        for (Element tabItem : tabItems)
        {
            // each tabitem contains the widget name to add as a ref attribute,
            // and other information (title, icon, tooltip) as a child element
            Attribute refAttribute = tabItem
                    .getAttribute(SwingXMLBuilder.REF_ATTRIBUTE);
            if (refAttribute == null)
            {
                throw SwingXMLBuilder.createException(
                        "tabitem requires a ref attribute", pElement);
            }
            // store mapping
            String refName = refAttribute.getValue();
            Object[] mapValue = new Object[3];
            if (pTabMapping.containsKey(refName))
            {
                throw SwingXMLBuilder.createException(
                        "non uniq refName in tabmapping: " + refName, pElement);
            }
            pTabMapping.put(refName, mapValue);
            // initialize title with widget name
            mapValue[0] = refName;
            // extract title
            mapValue[0] = mBuilder.getTitle(tabItem);
            // extract icon
            for (Element iconElement : tabItem.getChildren(SwingXMLBuilder.ICON_ELEMENT))
            {
                Attribute nameAttribute = iconElement.getAttribute(SwingXMLBuilder.NAME_ATTRIBUTE);
                if (mBuilder.isSameLanguage(iconElement) && (nameAttribute != null))
                {
                    String iconRelName = nameAttribute.getValue();
                    Icon icon = mBuilder.getIconCache().getIcon(iconRelName, IconCache.ICON_MODIFIER_NORMAL);
                    mapValue[1] = icon;
                }
            }
            // extract tooltip
            for (Element tooltipElement : tabItem.getChildren(SwingXMLBuilder.TOOLTIP_ELEMENT))
            {
                if (mBuilder.isSameLanguage(tooltipElement))
                {
                    String tooltip = tooltipElement.getText();
                    mapValue[2] = tooltip;
                }
            }
        }
    }

    /**
     * This method decorates the handed widget if the handed element does make
     * sense.
     *
     * @param pWidget
     *            pseudo widget or Container that will be decorated
     * @param pElement
     *            element describing the decoration
     */
    private void decorateWidget(Object pWidget, Element pElement)
    {
        String widgetDecorationName = pElement.getName();
    
        if (widgetDecorationName.equals(SwingXMLBuilder.PROPERTY_ELEMENT))
        {
            if (!(pWidget instanceof JComponent))
                throw SwingXMLBuilder.createException("can't set a property for non-JComponent "+pWidget, pElement);

            JComponent component = (JComponent) pWidget;
            String key = pElement.getAttributeValue(SwingXMLBuilder.KEY_ATTRIBUTE);
            if(key == null)
                throw SwingXMLBuilder.createException("invalid null key", pElement);

            Object value = NonVisualBuilderDelegate.getValue(mBuilder, pElement, key);

            component.putClientProperty(key, value);
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.TEXT_ELEMENT))
        {
            if (mBuilder.isSameLanguage(pElement))
            {
                if (pWidget instanceof JLabel)
                    ((JLabel) pWidget).setText(pElement.getText());
                else if (pWidget instanceof AbstractButton)
                    ((AbstractButton) pWidget).setText(pElement.getText());
                else if (pWidget instanceof TitledSeparator)
                    ((TitledSeparator) pWidget).setText(pElement.getText());
                else if (pWidget instanceof BuilderAppendSeparator)
                  ((BuilderAppendSeparator)pWidget).setText(pElement.getText());
            }
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.TITLE_ELEMENT))
        {
            if (mBuilder.isSameLanguage(pElement))
            {
                if (pWidget instanceof JComponent)
                    ((JComponent) pWidget).setBorder(new TitledBorder(pElement
                            .getText()));
                else if (pWidget instanceof JFrame)
                    ((JFrame) pWidget).setTitle(pElement.getText());
                else if (pWidget instanceof JDialog)
                    ((JDialog) pWidget).setTitle(pElement.getText());
            }
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.MNEMONIC_ELEMENT))
        {
            if (mBuilder.isSameLanguage(pElement))
            {
                if (pWidget instanceof AbstractButton)
                {
                    ((AbstractButton) pWidget).setMnemonic(pElement.getText()
                            .charAt(0));
                }
                else if (pWidget instanceof JLabel)
                {
                    ((JLabel) pWidget).setDisplayedMnemonic(pElement.getText()
                            .charAt(0));
                }
            }
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.ACCELERATOR_ELEMENT))
        {
            if (mBuilder.isSameLanguage(pElement)
                    && (pWidget instanceof JMenuItem))
            {
                String accelerator = pElement.getText();
                ((JMenuItem) pWidget).setAccelerator(KeyStroke
                        .getKeyStroke(accelerator));
            }
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.SHORTCUT_ELEMENT))
        {
            if (pWidget instanceof JComponent)
            {
                String key      = pElement.getAttributeValue(SwingXMLBuilder.KEY_ATTRIBUTE);
                String modifiers= pElement.getAttributeValue(SwingXMLBuilder.MODIFIERS_ATTRIBUTE);
                String condition= pElement.getAttributeValue(SwingXMLBuilder.CONDITION_ATTRIBUTE);
                String actionref= pElement.getAttributeValue(SwingXMLBuilder.ACTIONREF_ATTRIBUTE);

                try
                {

                    ((JComponent) pWidget).getActionMap().put(actionref, (Action) mBuilder.getNonVisualObject(actionref));

                    // set default values
                    int cond    = JComponent.WHEN_FOCUSED;
                    int mod     = 0; // == no modifiers

                    if(condition != null)
                    {
                        cond    = JComponent.class.getField(condition).getInt(condition);
                    }
                    if(modifiers != null)
                    {
                        mod     = KeyEvent.class.getField(modifiers).getInt(modifiers);
                    }

                    ((JComponent) pWidget).getInputMap(cond).put(
                        KeyStroke.getKeyStroke(KeyEvent.class.getField(key).getInt(key),mod),
                        actionref);

                }
                catch (ClassCastException e)
                {
                    throw SwingXMLBuilder.createException("could not get an Action for actionref " +
                                                          actionref + " for this component", e, pElement);
                }
                catch (Exception e)
                {
                    throw SwingXMLBuilder.createException("could not create shortcut from key: '" +
                                                          key + "', modifiers: '" + modifiers +
                                                          ", condition: '" + condition +
                                                          "' for this component", e, pElement);
                }
            }
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.TOOLTIP_ELEMENT))
        {
            if (mBuilder.isSameLanguage(pElement)
                    && (pWidget instanceof JComponent))
            {
                ((JComponent) pWidget).setToolTipText(pElement.getText());
            }
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.ICON_ELEMENT))
        {
            Attribute nameAttribute = pElement
                    .getAttribute(SwingXMLBuilder.NAME_ATTRIBUTE);
            if (mBuilder.isSameLanguage(pElement)
                    && (nameAttribute != null))
            {
                String iconName = nameAttribute.getValue();
                if (pWidget instanceof JMenuItem)
                {
                    JMenuItem menuItem = (JMenuItem) pWidget;
                    ImageIcon imageIcon = mBuilder.getIconCache().getIcon(
                            iconName, IconCache.ICON_MODIFIER_SMALL);
                    if (imageIcon != null)
                    {
                        menuItem.setIcon(imageIcon);
                    }
                }
                else if (pWidget instanceof AbstractButton)
                {
                    AbstractButton button   = (AbstractButton) pWidget;
                    IconCache      iconCache= mBuilder.getIconCache();
                    Icon           normal   = iconCache.getIcon(iconName,
                                                    IconCache.ICON_MODIFIER_NORMAL);
                    if (normal != null)
                    {
                        button.setIcon        (normal);
                        button.setDisabledIcon(
                                iconCache.getIcon(iconName,
                                                  IconCache.ICON_MODIFIER_DISABLED));
                        button.setPressedIcon(
                                iconCache.getIcon(iconName,
                                                  IconCache.ICON_MODIFIER_PRESSED));
                        button.setSelectedIcon(
                                iconCache.getIcon(iconName,
                                                  IconCache.ICON_MODIFIER_SELECTED));
                        button.setDisabledSelectedIcon(
                                iconCache.getIcon(iconName,
                                                  IconCache.ICON_MODIFIER_DISABLED_SELECTED));
                        Icon rollover= iconCache.getIcon(iconName,
                                                         IconCache.ICON_MODIFIER_ROLLOVER);
                        if (rollover == null)
                        {
                            button.setRolloverEnabled(false);
                        }
                        else
                        {
                            button.setRolloverEnabled(true);
                            button.setRolloverIcon(rollover);
                            button.setRolloverSelectedIcon(
                                    iconCache.getIcon(iconName,
                                                      IconCache.ICON_MODIFIER_ROLLOVER_SELECTED));
                        }
                    }
                }
                else if (pWidget instanceof JFrame)
                {
                    JFrame frame = (JFrame) pWidget;
                    ImageIcon imageIcon = mBuilder.getIconCache().getIcon(
                            iconName, IconCache.ICON_MODIFIER_SMALL);
                    if (imageIcon != null)
                    {
                        frame.setIconImage(imageIcon.getImage());
                    }
                }
                else if (pWidget instanceof JLabel)
                {
                    JLabel label = (JLabel) pWidget;
                    ImageIcon imageIcon = mBuilder.getIconCache().getIcon(
                            iconName, IconCache.ICON_MODIFIER_NORMAL);
                    if (imageIcon != null)
                    {
                        label.setIcon(imageIcon);
                    }
                }
                else
                {
                    throw SwingXMLBuilder.createException(
                            "no icon support for " + pWidget, pElement);
                }
            }
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.COMBOITEM_ELEMENT))
        {
            if (mBuilder.isSameLanguage(pElement)
                    && (pWidget instanceof JComboBox))
            {
                JComboBox combobox = (JComboBox) pWidget;
                String comboboxItem = pElement.getTextTrim();
                if (!"".equals(comboboxItem))
                {
                    combobox.addItem(comboboxItem);
                }
            }
        }
        else if (widgetDecorationName
                .equals(SwingXMLBuilder.TABMAPPING_ELEMENT))
        {
            if (pWidget instanceof JTabbedPane)
            {
                JTabbedPane tabbedPane = (JTabbedPane) pWidget;
                Map tabMapping = (Map) tabbedPane
                        .getClientProperty(SwingXMLBuilder.TABMAPPING_PROPERTY);
                if (tabMapping == null)
                {
                    tabMapping = new HashMap();
                    tabbedPane.putClientProperty(
                            SwingXMLBuilder.TABMAPPING_PROPERTY, tabMapping);
                }
                // extract and store mapping
                storeTabMapInformation(tabMapping, pElement);
            }
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.POPUPREF_ELEMENT))
        {
            if (pWidget instanceof JPopupMenu)
            {
                JPopupMenu popup = (JPopupMenu) pWidget;
                PopupManager popupManger = (PopupManager) popup
                        .getClientProperty(PopupManager.POPUPMANAGER_PROPERTY);
                Attribute refAttribute = pElement
                        .getAttribute(SwingXMLBuilder.REF_ATTRIBUTE);
                JComponent component;
                if (refAttribute != null)
                {
                    String widgetName = refAttribute.getValue();
                    component = mBuilder.getComponentByAnyName(widgetName);
                    if (component != null)
                    {
                        popupManger.addManagedComponent(component);
                    }
                }
            }
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.LAYOUTMANAGER_ELEMENT)
                && (pWidget instanceof Container))
        {
            Container  container   = (Container) pWidget;
            Attribute typeAttribute= pElement.getAttribute(SwingXMLBuilder.TYPE_ATTRIBUTE);
            if (typeAttribute != null)
            {
                // create layout manager from type
                String        layoutType     = typeAttribute.getValue();
                LayoutManager layoutManager  = null;
                boolean       foundLayoutType= true;
                try
                {
                    if (layoutType.equals(SwingXMLBuilder.GRIDBAG_LAYOUT))
                    {
                        layoutManager = new GridBagLayout();
                    }
                    else if (layoutType.equals(SwingXMLBuilder.NULL_LAYOUT))
                    {
                        layoutManager = null;
                    }
                    else if (layoutType.equals(SwingXMLBuilder.BORDER_LAYOUT))
                    {
                        Element child;
                        int hgap = 0;
                        int vgap = 0;
                        if ((child = pElement.getChild(SwingXMLBuilder.HGAP_ELEMENT)) != null)
                        {
                            hgap = Integer.parseInt(child.getTextTrim());
                        }
                        if ((child = pElement.getChild(SwingXMLBuilder.VGAP_ELEMENT)) != null)
                        {
                            vgap = Integer.parseInt(child.getTextTrim());
                        }
                        layoutManager = new BorderLayout(hgap, vgap);
                    }
                    else if (layoutType.equals(SwingXMLBuilder.BOX_LAYOUT))
                    {
                        Element child;
                        int axis = 0;
                        if ((child = pElement.getChild(SwingXMLBuilder.AXIS_ELEMENT)) != null)
                        {
                            axis = Integer.parseInt(child.getTextTrim());
                        }
                        layoutManager = new BoxLayout(container, axis);
                    }
                    else if (layoutType.equals(SwingXMLBuilder.CARD_LAYOUT))
                    {
                        Element child;
                        int hgap = 0;
                        int vgap = 0;
                        if ((child = pElement.getChild(SwingXMLBuilder.HGAP_ELEMENT)) != null)
                        {
                            hgap = Integer.parseInt(child.getTextTrim());
                        }
                        if ((child = pElement.getChild(SwingXMLBuilder.VGAP_ELEMENT)) != null)
                        {
                            vgap = Integer.parseInt(child.getTextTrim());
                        }
                        layoutManager = new CardLayout(hgap, vgap);
                    }
                    else if (layoutType.equals(SwingXMLBuilder.FLOW_LAYOUT))
                    {
                        Element child;
                        int align = 0;
                        int hgap = 0;
                        int vgap = 0;
                        if ((child = pElement.getChild(SwingXMLBuilder.ALIGN_ELEMENT)) != null)
                        {
                            align = Integer.parseInt(child.getTextTrim());
                        }
                        if ((child = pElement.getChild(SwingXMLBuilder.HGAP_ELEMENT)) != null)
                        {
                            hgap = Integer.parseInt(child.getTextTrim());
                        }
                        if ((child = pElement.getChild(SwingXMLBuilder.VGAP_ELEMENT)) != null)
                        {
                            vgap = Integer.parseInt(child.getTextTrim());
                        }
                        layoutManager = new FlowLayout(align, hgap, vgap);
                    }
                    else if (layoutType.equals(SwingXMLBuilder.GRID_LAYOUT))
                    {
                        Element child;
                        int rows = 0;
                        int cols = 0;
                        int hgap = 0;
                        int vgap = 0;
                        if ((child = pElement.getChild(SwingXMLBuilder.ROWS_ELEMENT)) != null)
                        {
                            rows = Integer.parseInt(child.getTextTrim());
                        }
                        if ((child = pElement.getChild(SwingXMLBuilder.COLUMNS_ELEMENT)) != null)
                        {
                            cols = Integer.parseInt(child.getTextTrim());
                        }
                        if ((child = pElement.getChild(SwingXMLBuilder.HGAP_ELEMENT)) != null)
                        {
                            hgap = Integer.parseInt(child.getTextTrim());
                        }
                        if ((child = pElement.getChild(SwingXMLBuilder.VGAP_ELEMENT)) != null)
                        {
                            vgap = Integer.parseInt(child.getTextTrim());
                        }
                        layoutManager = new GridLayout(rows, cols, hgap, vgap);
                    }
                    else if (layoutType.equals(SwingXMLBuilder.TABLE_LAYOUT))
                    {
                        String columns= pElement.getChildText(SwingXMLBuilder.COLUMNS_ELEMENT);
                        String rows   = pElement.getChildText(SwingXMLBuilder.ROWS_ELEMENT);
                        layoutManager = new TableLayout2(columns, rows);
                    }
                    else if (layoutType.equals(SwingXMLBuilder.FORM_LAYOUT))
                    {
                        layoutManager = createFormLayout(pElement);
                    }
                    else if (layoutType.equals(SwingXMLBuilder.FLEXIBLEGRID_LAYOUT))
                    {
                        if (!(pWidget instanceof JPanel))
                        {
                            throw SwingXMLBuilder.createException(
                                    "FlexibleGridLayout can only be set on a JPanel, not for a "
                                    + pWidget.getClass().getName(), pElement);
                        }
                        FlexibleGridLayout flexibleGridLayout = new FlexibleGridLayout((JPanel) pWidget);
                        Element child;
                        if ((child = pElement.getChild(SwingXMLBuilder.VGAP_ELEMENT)) != null)
                        {
                            flexibleGridLayout.setVgap(Integer.parseInt(child.getTextTrim()));
                        }
                        if ((pElement.getChild(SwingXMLBuilder.COLUMNS_ELEMENT) != null)
                                && (pElement.getChild(SwingXMLBuilder.ROWS_ELEMENT) != null))
                        {
                            throw SwingXMLBuilder.createException(
                                    "can't set both columns and rows", pElement);
                        }
                        if ((child = pElement.getChild(SwingXMLBuilder.COLUMNS_ELEMENT)) != null)
                        {
                            flexibleGridLayout.setDefaultBreak(Integer.parseInt(child.getTextTrim()));
                        }
                        else if ((child = pElement.getChild(SwingXMLBuilder.ROWS_ELEMENT)) != null)
                        {
                            flexibleGridLayout.setDefaultBreak(Integer.parseInt(child.getTextTrim()));
                        }
                        layoutManager = flexibleGridLayout;
                    }
                    else
                    {
                        foundLayoutType = false;
                    }
                }
                catch (Exception e)
                {
                    throw SwingXMLBuilder.createException(
                            "could not create layoutmanager for layout "
                                    + layoutType, e, pElement);
                }
                if (!foundLayoutType)
                {
                    // finally check the class attribute
                    String className = pElement
                            .getAttributeValue(SwingXMLBuilder.CLASS_ATTRIBUTE);
                    if (className != null)
                    {
                        try
                        {
                            layoutManager= (LayoutManager)Class.forName(className).newInstance();
                        }
                        catch (Exception e)
                        {
                            throw SwingXMLBuilder.createException(
                                    "could not create layoutmanager class= "
                                            + className, e, pElement);
                        }
                    }
                    else
                    {
                        throw SwingXMLBuilder.createException("unknown layout "
                                + layoutType, pElement);
                    }
                }
                container.setLayout(layoutManager);
            }
            else
            {
                throw SwingXMLBuilder.createException("layout without type",
                        pElement);
            }
        }
        // CONSTRAINT_ELEMENT is already handled in createWidget()
        else if (widgetDecorationName.equals(SwingXMLBuilder.BORDER_ELEMENT) &&
                 (pWidget instanceof JComponent)                                )
        {
            addBorder(pElement, (JComponent) pWidget);
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.MINSIZE_ELEMENT) && (pWidget instanceof JComponent))
        {
        	((JComponent)pWidget).setMinimumSize(parseSizeTag(pElement));
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.MAXSIZE_ELEMENT) && (pWidget instanceof JComponent))
        {
        	((JComponent)pWidget).setMaximumSize(parseSizeTag(pElement));
        }
        else if (widgetDecorationName.equals(SwingXMLBuilder.PREFSIZE_ELEMENT) && (pWidget instanceof JComponent))
        {
        	((JComponent)pWidget).setPreferredSize(parseSizeTag(pElement));
        }
    }
    
    /**
     * Parses the content of a minsize, maxsize or prefsize tag and converts it into an Dimension object.
     * @param pElement The tag element.
     * @return The specified size as a Dimension object.
     */
    protected Dimension parseSizeTag(Element pElement)
    {
    	String[] size = pElement.getValue().split(",");
    	return new Dimension(Integer.parseInt(size[0]), Integer.parseInt(size[1]));
    }

    /**
     * Tests if the given node is a ("new") widget and not a widget description.
     * The widget may also be a "pseudo" widget used for the form builder
     * support.
     *
     * @param pElement
     *            node to test
     * @return true if the elment node is a new widget
     * @noinspection RedundantIfStatement
     */
    private boolean isWidgetElement(Element pElement)
    {
        String widgetTypeName = pElement.getName();
        if (widgetTypeName.equals(SwingXMLBuilder.FRAME_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.DIALOG_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.PANEL_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.ANY_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.BUTTON_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.LABEL_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.RADIOBUTTON_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.TOGGLEBUTTON_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.CHECKBOX_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.TEXTFIELD_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.PASSWORDFIELD_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.TEXTAREA_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.COMBOBOX_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.SLIDER_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.SPLITPANE_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.SCROLLPANE_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.TABBEDPANE_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.LIST_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.TABLE_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.TREE_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.SEPARATOR_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.SEPARATORPANEL_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.MENUBAR_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.MENU_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.MENU_ITEM_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.TOOLBAR_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.TOOLBAR_ITEM_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.POPUP_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.POPUPMENU_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.POPUP_ITEM_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.BUILDER_ELEMENT))
            return true;
        else if (widgetTypeName.equals(SwingXMLBuilder.SPINNER_ELEMENT))
            return true;
        else
            return false;
    }

    /**
     * Create a widget for the handed element.
     * @param pParent null or parent of the widget
     * @param pElement widget as XML Element
     * @return widget/constrain pair
     */
    private WidgetElement createWidget(Container pParent, Element pElement)
    {
        String widgetTypeName= pElement.getName();
        Object widget;
        if (widgetTypeName.equals(SwingXMLBuilder.FRAME_ELEMENT))
            widget = createFrame(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.DIALOG_ELEMENT))
            widget = createDialog(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.PANEL_ELEMENT))
            widget = createPanel(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.ANY_ELEMENT))
            widget = createAny(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.BUTTON_ELEMENT))
            widget = createButton(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.LABEL_ELEMENT))
            widget = createLabel(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.RADIOBUTTON_ELEMENT))
            widget = createRadioButton(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.TOGGLEBUTTON_ELEMENT))
            widget = createToggleButton(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.CHECKBOX_ELEMENT))
            widget = createCheckBox(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.TEXTFIELD_ELEMENT))
            widget = createTextField(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.PASSWORDFIELD_ELEMENT))
            widget = createPasswordField(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.TEXTAREA_ELEMENT))
            widget = createTextArea(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.COMBOBOX_ELEMENT))
            widget = createComboBox(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.SLIDER_ELEMENT))
            widget = createSlider(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.SPLITPANE_ELEMENT))
            widget = createSplitPane(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.SCROLLPANE_ELEMENT))
            widget = createScrollPane(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.TABBEDPANE_ELEMENT))
            widget = createTabbedPane(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.LIST_ELEMENT))
            widget = createList(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.TABLE_ELEMENT))
            widget = createTable(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.TREE_ELEMENT))
            widget = createTree(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.SEPARATOR_ELEMENT))
            widget = createSeparator(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.SEPARATORPANEL_ELEMENT))
            widget = createSeparatorPanel(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.MENUBAR_ELEMENT))
            widget = createMenubar(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.MENU_ELEMENT))
            widget = createMenu(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.MENU_ITEM_ELEMENT))
            widget = createMenuItem(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.TOOLBAR_ELEMENT))
            widget = createToolbar(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.TOOLBAR_ITEM_ELEMENT))
            widget = createToolbarItem(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.POPUP_ELEMENT))
            widget = createPopup(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.POPUPMENU_ELEMENT))
            widget = createPopupMenu(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.POPUP_ITEM_ELEMENT))
            widget = createPopupItem(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.BUILDER_ELEMENT))
            widget = createBuilder(pParent, pElement);
        else if (widgetTypeName.equals(SwingXMLBuilder.SPINNER_ELEMENT))
            widget = createSpinner(pParent, pElement);
        else
            throw SwingXMLBuilder.createException("unknown widget "+ widgetTypeName, pElement);

        WidgetElement widgetElement;
        if ((widget instanceof Container) || (widget==null))
        {
            widgetElement = new WidgetElement((Container) widget, createConstraint(pElement));
        }
        else if (widget instanceof WidgetElement)
        {
            widgetElement = (WidgetElement) widget;
        }
        else
        {
            throw SwingXMLBuilder.createException("widgets of type "+
                                                  widget.getClass().getName() +
                                                  " are not supported");
        }

        String name= null;

        // use id as the widget's name
        Attribute id = pElement.getAttribute(SwingXMLBuilder.ID_ATTRIBUTE);
        boolean setName= (id!=null);
        if (setName)
        {
            name = id.getValue();
            widgetElement.getComponent().setName(name);
        }

        // to enable that the children of "any" objects are also part of our maps,
        // we support a recursive name import
        String  importNames= pElement.getAttributeValue(SwingXMLBuilder.IMPORTNAMES_ATTRIBUTE);
        boolean recurse= "true".equalsIgnoreCase(importNames);
        if (recurse)
        {
            // check if the name is not null
            name = widgetElement.getComponent().getName();
            if (name==null)
            {
                throw SwingXMLBuilder.createException("can't import names of the elment name is not set", pElement);
            }
        }

        if (setName || recurse)
        {
            String prefix;
            if (pParent != null)
            {
                prefix = mBuilder.getNameByContainer(pParent);
                if (prefix == null)
                {
                    throw SwingXMLBuilder.createException("parent of name "+ name +
                                                          " has no name", pElement);
                }
            }
            else
            {
                prefix = "";
                if (mBuilder.getContainerByName(name) != null)
                {
                    throw SwingXMLBuilder.createException("top level name "+ name + " is not uniq",
                                                          pElement);
                }
            }

            importMappings(pElement, prefix, widgetElement.getComponent(), recurse);
        }

        return widgetElement;
    }

    /**
     * This method recursivly adds all named components.
     *
     * @param   pPrefix an empty string or the concatenate name of our parents (without a trailing /)
     * @param   pNode   the current examined container node
     * @param   pRecurse if we should recurse
     * @param   pElement (root) widget as XML Element
     * @throws  IllegalArgumentException if the names inside the component are somehow wrong
     */
    private void importMappings(Element pElement, String pPrefix, Container pNode, boolean pRecurse)
    {
        // if the widget has no name and is no viewport, we have nothing to do
        String  myName      = pNode.getName();
        boolean hasName     = (myName!=null);
        boolean isScrollPane= (pNode instanceof JViewport);
        if (!hasName &&!isScrollPane)
        {
            return;
        }

        String newPrefix;
        if (isScrollPane)
        {
            newPrefix= pPrefix;
        }
        else
        {
            // check if the name contains no /
            if (myName.contains(SwingXMLBuilder.SEPARATOR))
            {
                throw SwingXMLBuilder.createException("name " + myName +
                                                      "invalid (no slash allowed)",
                                                      pElement);
            }

            // build the full name
            StringBuilder sb = new StringBuilder(pPrefix.length() + SwingXMLBuilder.SEPARATOR.length() + myName.length());
            sb.append(pPrefix);
            if (pPrefix.length()>1)
                sb.append(SwingXMLBuilder.SEPARATOR);
            sb.append(myName);
            String fullName= sb.toString();

            if (mBuilder.getContainerByName(fullName) != null)
            {
                throw SwingXMLBuilder.createException("name " + fullName + " contained twice in parent", pElement);
            }

            mBuilder.getNameToVisual().     put(fullName, pNode);
            mBuilder.getShortNameToVisual().put(myName,   pNode);
            mBuilder.getVisualToName().     put(pNode, fullName);

            newPrefix= fullName;
        }

        if (pRecurse)
        {
            Component[] children= pNode.getComponents();
            for (Component child : children)
            {
                if (child instanceof Container)
                {
                    importMappings(pElement, newPrefix, (Container) child, true);
                }
            }
        }
    }

    private JFrame createFrame(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        JFrame frame = (JFrame) mBuilder.getWidgetFactory().create(JFrame.class.getName(), pElement, pParent);
        Attribute closeActionAttribute = pElement.getAttribute(SwingXMLBuilder.CLOSEACTION_ATTRIBUTE);
        if (closeActionAttribute == null)
        {
            // we close the app if nothing is specified
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        else
        {
            String closeAction = closeActionAttribute.getValue();
            final DispatcherAction action = (DispatcherAction) mBuilder.getNameToNonVisual().get(closeAction);
            if (action == null)
            {
                throw SwingXMLBuilder.createException("unknown closeAction attribute"+ closeAction, pElement);
            }
            frame.addWindowListener(new WindowAdapter()
            {
                public void windowClosing(WindowEvent e)
                {
                    ActionEvent actionEvent = new ActionEvent(e.getSource(), e.getID(), "WINDOW_CLOSING");
                    action.actionPerformed(actionEvent);
                }
            });
            // when somebody specifies a close operation, there should be no default
            frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        }
        return frame;
    }

    private JDialog createDialog(Container pParent, Element pElement)
    {
        JDialog dialog = (JDialog) mBuilder.getWidgetFactory().create(JDialog.class.getName(), pElement, pParent);
        // the default is to hide dialogs
        dialog.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

        String closeAction= pElement.getAttributeValue(SwingXMLBuilder.CLOSEACTION_ATTRIBUTE);
        if (closeAction != null)
        {
            final DispatcherAction action     = (DispatcherAction) mBuilder.getNameToNonVisual().get(closeAction);
            if (action == null)
            {
                throw SwingXMLBuilder.createException("unknown closeAction attribute" +
                                                      closeAction, pElement);
            }
            dialog.addWindowListener(new WindowAdapter()
            {
                public void windowClosing(WindowEvent e)
                {
                    ActionEvent actionEvent = new ActionEvent(e.getSource(), e.getID(), "WINDOW_CLOSING");
                    action.actionPerformed(actionEvent);
                }
            });
            // when somebody specifies a close operation, there should be no default
            dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        }

        String escapeAction= pElement.getAttributeValue(SwingXMLBuilder.ESCAPEACTION_ATTRIBUTE);
        if (escapeAction != null)
        {
            DispatcherAction action= (DispatcherAction) mBuilder.getNameToNonVisual().get(escapeAction);
            if (action == null)
            {
                throw SwingXMLBuilder.createException("unknown escapeAction attribute" +
                                                      escapeAction, pElement);
            }
            KeyStroke escStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
            InputMap  inputMap  = dialog.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
            ActionMap actionMap = dialog.getRootPane().getActionMap();
            inputMap.put(escStroke, SwingXMLBuilder.CANCEL_ACTION_KEY);
            actionMap.put(SwingXMLBuilder.CANCEL_ACTION_KEY, action);
            /*
             * for further details on input handling, see
             * http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html
             */
        }

        String modal= pElement.getAttributeValue(SwingXMLBuilder.MODAL_ATTRIBUTE);
        if ("true".equals(modal))
        {
            dialog.setModal(true);
        }

        return dialog;
    }

    private JPanel createPanel(Container pParent, Element pElement)
    {
        return (JPanel) mBuilder.getWidgetFactory().create(
                JPanel.class.getName(), pElement, pParent);
    }

    protected JComponent createAny(Container pParent, Element pElement)
    {
        JComponent component;
        Attribute classAttribute = pElement
                .getAttribute(SwingXMLBuilder.CLASS_ATTRIBUTE);
        if (classAttribute == null)
        {
            throw SwingXMLBuilder.createException("an any element needs a "
                    + SwingXMLBuilder.CLASS_ATTRIBUTE + " attribute", pElement);
        }
        String panelClassName = classAttribute.getValue();
        try
        {
            component = (JComponent) Class.forName(panelClassName).newInstance();
        }
        catch (Exception e)
        {
            throw SwingXMLBuilder.createException(
                    "could not create JComponent for an any element", e,
                    pElement);
        }
        return component;
    }

    private JButton createButton(Container pParent, Element pElement)
    {
        JButton button = (JButton) mBuilder.getWidgetFactory().create(JButton.class.getName(), pElement, pParent);
        // check if this button is buildNonVisual from an action
        DispatcherAction action = getAction(pElement, mBuilder.getNameToNonVisual());
        if (action != null)
        {
            button.setAction(action);
        }
        // check if this button is enabled
        Attribute enabledAttribute = pElement
                .getAttribute(SwingXMLBuilder.EDITABLE_ATTRIBUTE);
        if (enabledAttribute != null)
        {
            boolean enabled = "true".equals(enabledAttribute.getValue());
            button.setEnabled(enabled);
        }

        return button;
    }

    private JLabel createLabel(Container pParent, Element pElement)
    {
        JLabel label = (JLabel) mBuilder.getWidgetFactory().create(JLabel.class.getName(), pElement, pParent);
        Attribute orientationAttribute = pElement.getAttribute(SwingXMLBuilder.ALIGN_ATTRIBUTE);
        if (orientationAttribute != null)
        {
            int orientation = SwingConstants.LEFT;
            if ("center".equals(orientationAttribute.getValue()))
            {
                orientation = SwingConstants.CENTER;
            }
            else if ("right".equals(orientationAttribute.getValue()))
            {
                orientation = SwingConstants.RIGHT;
            }
            label.setHorizontalAlignment(orientation);
        }
        Attribute labelforAttribute = pElement.getAttribute(SwingXMLBuilder.LABELFOR_ATTRIBUTE);
        if (labelforAttribute != null)
        {
            Component labelfor = mBuilder.getComponentByAnyName(labelforAttribute.getValue());
            if (labelfor != null)
            {
                label.setLabelFor(labelfor);
            }
        }
        return label;
    }

    private JRadioButton createRadioButton(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        JRadioButton radioButton = (JRadioButton) mBuilder.getWidgetFactory()
                .create(JRadioButton.class.getName(), pElement, pParent);
        DispatcherAction action = getAction(pElement, mBuilder.getNameToNonVisual());
        if (action != null)
        {
            radioButton.setAction(action);
        }
        if (!(pParent instanceof JComponent))
        {
            throw SwingXMLBuilder.createException("parent of a radiobutton must be a JComponent", pElement);
        }
        JComponent parent      = (JComponent) pParent;
        ButtonGroup buttonGroup= (ButtonGroup) parent.getClientProperty(SwingXMLBuilder.BUTTONGROUP_PROPERTY);
        if (buttonGroup == null)
        {
            buttonGroup = new ButtonGroup();
            parent.putClientProperty(SwingXMLBuilder.BUTTONGROUP_PROPERTY, buttonGroup);
        }
        buttonGroup.add(radioButton);
        Attribute defaultAttribute = pElement.getAttribute(SwingXMLBuilder.DEFAULT_ATTRIBUTE);
        if ((defaultAttribute != null) && (SwingXMLBuilder.BUTTONGROUP_TRUE.equals(defaultAttribute.getValue())))
        {
            buttonGroup.setSelected(radioButton.getModel(), true);
        }
        return radioButton;
    }

    private JToggleButton createToggleButton(Container pParent, Element pElement)
    {
        JToggleButton toggleButton = (JToggleButton) mBuilder
                .getWidgetFactory().create(JToggleButton.class.getName(),
                        pElement, pParent);
        // check if this button is buildNonVisual from an action
        DispatcherAction action = getAction(pElement, mBuilder
                .getNameToNonVisual());
        if (action != null)
        {
            toggleButton.setAction(action);
        }
        return toggleButton;
    }

    private JCheckBox createCheckBox(Container pParent, Element pElement)
    {
        JCheckBox checkBox = (JCheckBox) mBuilder.getWidgetFactory().create(
                JCheckBox.class.getName(), pElement, pParent);
        // check if this button is buildNonVisual from an action
        DispatcherAction action = getAction(pElement, mBuilder
                .getNameToNonVisual());
        if (action != null && action.isToggle())
        {
            checkBox.setAction(action);
            checkBox.setModel(action.getToggleModel());
        }
        // check if this checkbox is enabled/disabled
        Attribute enabledAttribute = pElement
                .getAttribute(SwingXMLBuilder.ENABLED_ATTRIBUTE);
        if (enabledAttribute != null)
        {
            boolean enabled = "true".equals(enabledAttribute.getValue());
            checkBox.setEnabled(enabled);
        }
        // check if this checkbox is selected
        Attribute selectedAttribute = pElement
                .getAttribute(SwingXMLBuilder.SELECTED_ATTRIBUTE);
        if (selectedAttribute != null)
        {
            boolean selected = "true".equals(selectedAttribute.getValue());
            checkBox.setSelected(selected);
        }
        return checkBox;
    }

    private JTextField createTextField(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        JTextField textField;
        // check if we should take a formatted text field instead a normal text field
        // TODO create the formatted text field via factory: unfortunately, there is no
        // setFormatter() method, so we can't use the widget factory
        String maskFormat  = pElement .getAttributeValue(SwingXMLBuilder.MASKFORMAT_ATTRIBUTE);
        String dateFormat  = pElement .getAttributeValue(SwingXMLBuilder.DATEFORMAT_ATTRIBUTE);
        String numberFormat= pElement .getAttributeValue(SwingXMLBuilder.NUMBERFORMAT_ATTRIBUTE);
        if (maskFormat != null)
        {
            MaskFormatter formatter;
            try
            {
                formatter = new MaskFormatter(maskFormat);
            }
            catch (ParseException e)
            {
                throw SwingXMLBuilder.createException("could not create a " +
                                 "MaskFormatter for format " + maskFormat, e, pElement);
            }
            textField = new JFormattedTextField(formatter);
        }
        else if (dateFormat != null)
        {
            DateFormatter formatter;
            try
            {
                if ("".equals(dateFormat))
                    formatter = new DateFormatter(new SimpleDateFormat());
                else
                    formatter = new DateFormatter(new SimpleDateFormat(dateFormat));
            }
            catch (IllegalArgumentException e)
            {
                throw SwingXMLBuilder.createException("could not create a " +
                                 "DateFormatter for format " + dateFormat, e, pElement);
            }
            textField = new JFormattedTextField(formatter);
        }
        else if (numberFormat != null)
        {
            NumberFormatter formatter;
            try
            {
                formatter = new NumberFormatter(new DecimalFormat(numberFormat));
            }
            catch (IllegalArgumentException e)
            {
                throw SwingXMLBuilder.createException("could not create a " +
                                 "NumberFormatter for format " + numberFormat, e, pElement);
            }
            textField = new JFormattedTextField(formatter);
        }
        else
        {
            textField = (JTextField) mBuilder.getWidgetFactory().create(
                    JTextField.class.getName(), pElement, pParent);
        }
        // check if this textfield is enabled/disabled
        Attribute enabledAttribute = pElement
                .getAttribute(SwingXMLBuilder.ENABLED_ATTRIBUTE);
        if (enabledAttribute != null)
        {
            boolean enabled = "true".equals(enabledAttribute.getValue());
            textField.setEnabled(enabled);
        }
        // check if this text field gets a special document
        Attribute documentAttribute = pElement
                .getAttribute(SwingXMLBuilder.DOCUMENT_ATTRIBUTE);
        if (documentAttribute != null)
        {
            String   documentClass = documentAttribute.getValue();
            Document document;
            try
            {
                document = (Document) Class.forName(documentClass).newInstance();
                textField.setDocument(document);
            }
            catch (Exception e)
            {
                throw SwingXMLBuilder.createException(
                        "could not create Document", e, pElement);
            }
        }
        // check if the textfield is editable
        Attribute editableAttribute = pElement
                .getAttribute(SwingXMLBuilder.EDITABLE_ATTRIBUTE);
        if (editableAttribute != null)
        {
            boolean editable = "true".equals(editableAttribute.getValue());
            textField.setEditable(editable);
        }
        // check if we should set an alignment for the text inside the textfield
        Attribute alignAttribute = pElement
                .getAttribute(SwingXMLBuilder.ALIGN_ATTRIBUTE);
        if (alignAttribute != null)
        {
            int orientation = SwingConstants.LEFT;
            if ("center".equals(alignAttribute.getValue()))
            {
                orientation = SwingConstants.CENTER;
            }
            else if ("left".equals(alignAttribute.getValue()))
            {
                orientation = SwingConstants.LEFT;
            }
            else if ("right".equals(alignAttribute.getValue()))
            {
                orientation = SwingConstants.RIGHT;
            }
            textField.setHorizontalAlignment(orientation);
        }
        // check if we should set the width (number of columns)
        Attribute columnsAttribute = pElement
                .getAttribute(SwingXMLBuilder.COLUMNS_ATTRIBUTE);
        if (columnsAttribute != null)
        {
            int columns;
            try
            {
                columns = columnsAttribute.getIntValue();
            }
            catch (DataConversionException e)
            {
                throw SwingXMLBuilder.createException(
                        "could not create columns attributtes", e, pElement);
            }
            textField.setColumns(columns);
        }
        return textField;
    }

    private JPasswordField createPasswordField(Container pParent,
            Element pElement)
    {
        return (JPasswordField) mBuilder.getWidgetFactory().create(
                JPasswordField.class.getName(), pElement, pParent);
    }

    private JTextArea createTextArea(Container pParent, Element pElement)
    {
        JTextArea textArea = (JTextArea) mBuilder.getWidgetFactory().create(
                JTextArea.class.getName(), pElement, pParent);
        // check if the text area is editable
        Attribute editableAttribute = pElement
                .getAttribute(SwingXMLBuilder.EDITABLE_ATTRIBUTE);
        if (editableAttribute != null)
        {
            boolean editable = "true".equals(editableAttribute.getValue());
            textArea.setEditable(editable);
        }
        Attribute linewrapAttribute = pElement
                .getAttribute(SwingXMLBuilder.LINEWRAP_ATTRIBUTE);
        if (linewrapAttribute != null)
        {
            boolean linewrap = "true".equals(linewrapAttribute.getValue());
            textArea.setLineWrap(linewrap);
        }
        return textArea;
    }

    private JComboBox createComboBox(Container pParent, Element pElement)
    {
        JComboBox comboBox = (JComboBox) mBuilder.getWidgetFactory().create(
                JComboBox.class.getName(), pElement, pParent);
        // check if this combobox is enabled/disabled
        Attribute enabledAttribute = pElement.getAttribute(SwingXMLBuilder.ENABLED_ATTRIBUTE);
        if (enabledAttribute != null)
        {
            boolean enabled = "true".equals(enabledAttribute.getValue());
            comboBox.setEnabled(enabled);
        }
        return comboBox;
    }

    private JSlider createSlider(Container pParent, Element pElement)
    {
        return (JSlider) mBuilder.getWidgetFactory().create(
                JSlider.class.getName(), pElement, pParent);
    }

    private JSplitPane createSplitPane(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        JSplitPane splitPane = (JSplitPane) mBuilder.getWidgetFactory().create(
                JSplitPane.class.getName(), pElement, pParent);
        // orientation is 1 (HORIZONTAL_SPLIT) or 0 (VERTICAL_SPLIT)
        int orientation = 1;
        Attribute orientationAttribute = pElement
                .getAttribute(SwingXMLBuilder.ORIENTATION_ATTRIBUTE);
        if (orientationAttribute != null)
        {
            try
            {
                orientation = orientationAttribute.getIntValue();
            }
            catch (DataConversionException e)
            {
                throw SwingXMLBuilder.createException(
                        "wrong splitpane orientation " + orientationAttribute,
                        e, pElement);
            }
        }
        splitPane.setOrientation(orientation);
        Attribute oneTouchExpandableAttribute = pElement
                .getAttribute(SwingXMLBuilder.ONETOUCHEXPANDABLE_ATTRIBUTE);
        if (oneTouchExpandableAttribute != null)
        {
            splitPane.setOneTouchExpandable(true);
        }
        return splitPane;
    }

    private JScrollPane createScrollPane(Container pParent, Element pElement)
    {
        JScrollPane scrollPane = (JScrollPane) mBuilder.getWidgetFactory().create(JScrollPane.class.getName(), pElement, pParent);
        int vertical  = JScrollPane.VERTICAL_SCROLLBAR_ALWAYS;
        int horizontal= JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS;
        String vValue = pElement.getAttributeValue(SwingXMLBuilder.VERTICAL_SCROLLBAR_ATTRIBUTE);
        if (vValue != null)
        {
            if (SwingXMLBuilder.SCROLLBAR_AS_NEEDED.equals(vValue))
                vertical = JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED;
            else if (SwingXMLBuilder.SCROLLBAR_ALWAYS.equals(vValue))
                vertical = JScrollPane.VERTICAL_SCROLLBAR_ALWAYS;
            else if (SwingXMLBuilder.SCROLLBAR_NEVER.equals(vValue))
                vertical = JScrollPane.VERTICAL_SCROLLBAR_NEVER;
        }
        String hValue = pElement.getAttributeValue(SwingXMLBuilder.HORIZONTAL_SCROLLBAR_ATTRIBUTE);
        if (hValue != null)
        {
            if (SwingXMLBuilder.SCROLLBAR_AS_NEEDED.equals(hValue))
                horizontal = JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED;
            else if (SwingXMLBuilder.SCROLLBAR_ALWAYS.equals(hValue))
                horizontal = JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS;
            else if (SwingXMLBuilder.SCROLLBAR_NEVER.equals(hValue))
                horizontal = JScrollPane.HORIZONTAL_SCROLLBAR_NEVER;
        }
        scrollPane.setHorizontalScrollBarPolicy(horizontal);
        scrollPane.setVerticalScrollBarPolicy(vertical);
        return scrollPane;
    }

    private JTabbedPane createTabbedPane(Container pParent, Element pElement)
    {
        JTabbedPane tabbedPane = (JTabbedPane) mBuilder.getWidgetFactory()
                .create(JTabbedPane.class.getName(), pElement, pParent);
        int tabPlacement = JTabbedPane.TOP;
        Attribute tabPlacementAttribute = pElement
                .getAttribute(SwingXMLBuilder.TABPLACEMENT_ATTRIBUTE);
        if (tabPlacementAttribute != null)
        {
            tabPlacement = Integer.parseInt(tabPlacementAttribute.getValue());
        }
        tabbedPane.setTabPlacement(tabPlacement);
        return tabbedPane;
    }

    private JList createList(Container pParent, Element pElement)
    {
        return (JList) mBuilder.getWidgetFactory().create(
                JList.class.getName(), pElement, pParent);
    }

    private JTable createTable(Container pParent, Element pElement)
    {
        return (JTable) mBuilder.getWidgetFactory().create(
                JTable.class.getName(), pElement, pParent);
    }

    private JTree createTree(Container pParent, Element pElement)
    {
        return (JTree) mBuilder.getWidgetFactory().create(
                JTree.class.getName(), pElement, pParent);
    }

    private JSeparator createSeparator(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        if (pParent instanceof JMenu)
        {
            ((JMenu) pParent).addSeparator();
        }
        else if (pParent instanceof JPopupMenu)
        {
            ((JPopupMenu) pParent).addSeparator();
        }
        else if (pParent instanceof JToolBar)
        {
            ((JToolBar) pParent).addSeparator();
        }
        else
        {
            return (JSeparator) mBuilder.getWidgetFactory()
                    .create(JSeparator.class.getName(), pElement, pParent);
        }
        return null;
    }

    private TitledSeparator createSeparatorPanel(Container pParent,
            Element pElement)
    {
        return (TitledSeparator) mBuilder
                .getWidgetFactory().create(TitledSeparator.class.getName(),
                        pElement, pParent);
    }

    private JMenuBar createMenubar(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        return (JMenuBar) mBuilder.getWidgetFactory().create(
                JMenuBar.class.getName(), pElement, pParent);
    }

    private JMenu createMenu(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        return (JMenu) mBuilder.getWidgetFactory().create(
                JMenu.class.getName(), pElement, pParent);
    }

    private JMenuItem createMenuItem(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        JMenuItem menuItem;
        // check if this menu item is buildNonVisual from an action
        DispatcherAction action = getAction(pElement, mBuilder
                .getNameToNonVisual());
        if (action != null)
        {
            if (action.isToggle())
            {
                menuItem = (JCheckBoxMenuItem) mBuilder.getWidgetFactory()
                        .create(JCheckBoxMenuItem.class.getName(), pElement,
                                pParent);
                menuItem.setAction(action);
                menuItem.setModel(action.getToggleModel());
            }
            else
            {
                menuItem = (JMenuItem) mBuilder.getWidgetFactory().create(
                        JMenuItem.class.getName(), pElement, pParent);
                menuItem.setAction(action);
            }
        }
        else
        {
            menuItem = (JMenuItem) mBuilder.getWidgetFactory().create(
                    JMenuItem.class.getName(), pElement, pParent);
        }
        return menuItem;
    }

    private JToolBar createToolbar(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        return (JToolBar) mBuilder.getWidgetFactory().create(
                JToolBar.class.getName(), pElement, pParent);
    }
    private JButton createToolbarItem(Container pParent, Element pElement)
    {
        JButton button = createButton(pParent, pElement);

        // (somehow) a hack: we remove the text, so we get the "real" toolbar look,
        // but only when we where build from an action
        if (button.getAction()!=null)
        {
            button.setText(null);
        }

        // check if this toolbar item is enabled/disabled
        Attribute enabledAttribute = pElement.getAttribute(SwingXMLBuilder.ENABLED_ATTRIBUTE);
        if (enabledAttribute != null)
        {
            boolean enabled = "false".equals(enabledAttribute.getValue());
            button.setEnabled(enabled);
        }
        return button;
    }

    private JPopupMenu createPopup(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        return (JPopupMenu) mBuilder.getWidgetFactory().create(
                JPopupMenu.class.getName(), pElement, pParent);
    }

    private JMenu createPopupMenu(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        return createMenu(pParent, pElement);
    }

    private JMenuItem createPopupItem(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        return createMenuItem(pParent, pElement);
    }

    private WidgetElement createBuilder(Container pParent, Element pElement)
            throws IllegalArgumentException
    {
        String type   = pElement.getAttributeValue(SwingXMLBuilder.TYPE_ATTRIBUTE);
        String command= pElement.getAttributeValue(SwingXMLBuilder.COMMAND_ATTRIBUTE);

        if (((type==null) && (command==null)) ||
            ((type!=null) && (command!=null))   )
        {
            throw SwingXMLBuilder.createException("builder must either have a type or command attribute",
                                                  pElement);
        }

        if (type!=null)
        {
            // create a new panel builder, this is not a pseudo widget
            if (!"default".equals(type))
            {
                throw SwingXMLBuilder.createException("only know how to create DefaultFormBuilders",
                                                      pElement);
            }
            if (!(pParent instanceof JPanel))
            {
                throw SwingXMLBuilder.createException("builder only works with a JPanel",
                                                      pElement);
            }

            Element layoutElement= pElement.getChild(SwingXMLBuilder.LAYOUTMANAGER_ELEMENT);
            String  layoutType   = layoutElement==null ? null : layoutElement.getAttributeValue(SwingXMLBuilder.TYPE_ATTRIBUTE);
            if ((layoutElement==null) || !SwingXMLBuilder.FORM_LAYOUT.equals(layoutType))
            {
                throw SwingXMLBuilder.createException("builder needs a FormLayout", pElement);
            }

            JPanel             panel  = (JPanel)pParent;
            FormLayout         layout = createFormLayout(layoutElement);
            DefaultFormBuilder builder= new DefaultFormBuilder(layout, panel);
            panel.putClientProperty(SwingXMLBuilder.FORMBUILDER_PROPERTY, builder);

            return new WidgetElement(null);
        }
        else
        {
            // create a new pseudo widget to act later on the parent during the
            // add-all-children process
            PseudoWidget pseudoWidget;
            if ("appendSeparator".equals(command))
            {
                pseudoWidget= new BuilderAppendSeparator();
            }
            else if ("nextLine".equals(command))
            {
                pseudoWidget= BuilderNextLine.NEXT_LINE;
            }
            else if (command.startsWith("appendRow"))
            {
                pseudoWidget= new BuilderAppendRow(command.substring(command.indexOf(':')+1));
            }
            else
            {
                throw SwingXMLBuilder.createException(
                        "unknown builder command "+command, pElement);
            }
            return new WidgetElement(pseudoWidget);
        }
    }

    private JSpinner createSpinner(Container pParent, Element pElement)
    {
        return (JSpinner) mBuilder.getWidgetFactory().create(
                JSpinner.class.getName(), pElement, pParent);
    }

    //  TODO: Methoden dieses Typs public und static machen (wg. ObjectFactory).
    protected DispatcherAction getAction(Element pElement, Map pNameToNonVisual)
            throws IllegalArgumentException
    {
        Attribute actionrefAttribute = pElement
                .getAttribute(SwingXMLBuilder.ACTIONREF_ATTRIBUTE);
        if (actionrefAttribute != null)
        {
            String actionref = actionrefAttribute.getValue();
            DispatcherAction action = (DispatcherAction) pNameToNonVisual
                    .get(actionref);
            if (action == null)
            {
                throw SwingXMLBuilder.createException(
                        "unknown actionref attribute " + actionref, pElement);
            }
            return action;
        }
        return null;
    }

    private Object createConstraint(Element pElement) throws IllegalArgumentException
    {
        Object  constraintObject = null;
        Element constraintElement= pElement
                .getChild(SwingXMLBuilder.CONSTRAINT_ELEMENT);
        if (constraintElement != null)
        {
            Attribute typeAttribute = constraintElement
                    .getAttribute(SwingXMLBuilder.TYPE_ATTRIBUTE);
            if (typeAttribute != null)
            {
                // generate constraint from type
                String constraintType= typeAttribute.getValue();
                if (constraintType.equals(SwingXMLBuilder.GRIDBAG_LAYOUT))
                {
                    GridBagConstraints constraint = new GridBagConstraints();
                    Element child;
                    if ((child = constraintElement.getChild("gridx")) != null)
                    {
                        constraint.gridx = Integer
                                .parseInt(child.getTextTrim());
                    }
                    if ((child = constraintElement.getChild("gridy")) != null)
                    {
                        constraint.gridy = Integer
                                .parseInt(child.getTextTrim());
                    }
                    if ((child = constraintElement.getChild("fill")) != null)
                    {
                        constraint.fill = Integer.parseInt(child.getTextTrim());
                    }
                    if ((child = constraintElement.getChild("weightx")) != null)
                    {
                        constraint.weightx = Double.parseDouble(child
                                .getTextTrim());
                    }
                    if ((child = constraintElement.getChild("weighty")) != null)
                    {
                        constraint.weighty = Double.parseDouble(child
                                .getTextTrim());
                    }
                    if ((child = constraintElement.getChild("gridheight")) != null)
                    {
                        constraint.gridheight = Integer.parseInt(child
                                .getTextTrim());
                    }
                    if ((child = constraintElement.getChild("gridwidth")) != null)
                    {
                        constraint.gridwidth = Integer.parseInt(child
                                .getTextTrim());
                    }
                    if ((child = constraintElement.getChild("insets")) != null)
                    {
                        constraint.insets = getInsets(child);
                    }
                    if ((child = constraintElement.getChild("anchor")) != null)
                    {
                        constraint.anchor = Integer.parseInt(child
                                .getTextTrim());
                    }
                    if ((child = constraintElement.getChild("ipadx")) != null)
                    {
                        constraint.ipadx = Integer
                                .parseInt(child.getTextTrim());
                    }
                    if ((child = constraintElement.getChild("ipady")) != null)
                    {
                        constraint.ipady = Integer
                                .parseInt(child.getTextTrim());
                    }
                    constraintObject = constraint;
                }
                else if (constraintType
                        .equals(SwingXMLBuilder.FLEXIBLEGRID_LAYOUT))
                {
                    Element child;
                    if ((child = constraintElement
                            .getChild(SwingXMLBuilder.LINEBREAK_ELEMENT)) != null)
                    {
                        String value = child.getTextTrim();
                        if ("no".equalsIgnoreCase(value))
                        {
                            constraintObject = FlexibleGridLayout.NO_LINE_BREAK;
                        }
                        else
                        {
                            constraintObject = FlexibleGridLayout.LINE_BREAK;
                        }
                    }
                }
                else
                {
                    throw SwingXMLBuilder.createException(
                            "unknown constraint type" + constraintType,
                            pElement);
                }
            }
            else
            {
                // no type => use the plain content, but only if it is not
                // nothing
                String constraint = constraintElement.getTextTrim();
                if (!"".equals(constraint))
                {
                    constraintObject = constraint;
                }
            }
        }
        return constraintObject;
    }

    /**
     * Small helper to extract top/left/bottom/right from a element.
     *
     * @param pElement
     *            parent for top/left/bottom/right
     * @return a inset object with top/left/bottom/right
     */
    private static Insets getInsets(Element pElement)
    {
        int top = 0;
        int left = 0;
        int bottom = 0;
        int right = 0;
        Element inset;
        if ((inset = pElement.getChild("top")) != null)
            top = Integer.parseInt(inset.getTextTrim());
        if ((inset = pElement.getChild("left")) != null)
            left = Integer.parseInt(inset.getTextTrim());
        if ((inset = pElement.getChild("bottom")) != null)
            bottom = Integer.parseInt(inset.getTextTrim());
        if ((inset = pElement.getChild("right")) != null)
            right = Integer.parseInt(inset.getTextTrim());
        return new Insets(top, left, bottom, right);
    }

    /**
     * WidgetElement is a helper class to return both a component (it may also
     * be a pseudo-widget) as well as its constraints.
     */
    private static class WidgetElement
    {
        // null or Swing object, or a JFrame/JDialog
        private Container   mComponent;
        // null constraint for mComponent
        private Object      mConstraint;
        // null or pseudo widget
        private PseudoWidget mPseudoWidget;

        public WidgetElement(Container pComponent, Object pConstraint)
        {
            mComponent   = pComponent;
            mConstraint  = pConstraint;
            mPseudoWidget= null;
        }

        public WidgetElement(PseudoWidget pPseudoWidget)
        {
            mComponent   = null;
            mConstraint  = null;
            mPseudoWidget= pPseudoWidget;
        }

        public Container getComponent()
        {
            return mComponent;
        }

        public Object getConstraint()
        {
            return mConstraint;
        }

        public boolean isPseudoWidget()
        {
            return (mPseudoWidget != null);
        }

        public PseudoWidget getPseudoWidget()
        {
            return mPseudoWidget;
        }

        public Object getWidget()
        {
            if (isPseudoWidget())
                return getPseudoWidget();
            else
                return getComponent();
        }
    }

    /**
     * PseudoWidget is the base class for all pseudo widgets. Pseudo widgets are
     * used instead of decorations to operate during the process of adding the
     * widgets to its parent. Pseudo widgets are mainly useful for the form
     * builder support.
     */
    private abstract static class PseudoWidget
    {
        public abstract void addToParent(Container pParent);
    }

    private static class BuilderAppendSeparator extends PseudoWidget
    {
        private String mText;

        public void setText(String pText)
        {
            mText= pText;
        }

        public void addToParent(Container pParent)
        {
            JPanel             panel  = (JPanel)pParent;
            DefaultFormBuilder builder= (DefaultFormBuilder)panel.getClientProperty(SwingXMLBuilder.FORMBUILDER_PROPERTY);
            builder.appendSeparator(mText);
        }
    }

    private static class BuilderNextLine extends PseudoWidget
    {
        // we only need one instance for this class
        public static final BuilderNextLine NEXT_LINE= new BuilderNextLine();

        public void addToParent(Container pParent)
        {
            JPanel             panel  = (JPanel)pParent;
            DefaultFormBuilder builder= (DefaultFormBuilder)panel.getClientProperty(SwingXMLBuilder.FORMBUILDER_PROPERTY);
            builder.nextLine();
        }
    }

    private static class BuilderAppendRow extends PseudoWidget
    {
        private String mRowSpec;

        public BuilderAppendRow(String pRowSpec)
        {
            mRowSpec= pRowSpec;
        }

        public void addToParent(Container pParent)
        {
            JPanel             panel  = (JPanel)pParent;
            DefaultFormBuilder builder= (DefaultFormBuilder)panel.getClientProperty(SwingXMLBuilder.FORMBUILDER_PROPERTY);
            builder.appendRow(mRowSpec);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy