Clover coverage report - groovy - 1.0-beta-8
Coverage timestamp: Fri Dec 17 2004 14:55:55 GMT
file stats: LOC: 896   Methods: 42
NCLOC: 748   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
SwingBuilder.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
  $Id: SwingBuilder.java,v 1.11 2004/12/15 07:06:39 spullara Exp $
 3   
 
 4   
  Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
 5   
 
 6   
  Redistribution and use of this software and associated documentation
 7   
  ("Software"), with or without modification, are permitted provided
 8   
  that the following conditions are met:
 9   
 
 10   
  1. Redistributions of source code must retain copyright
 11   
     statements and notices.  Redistributions must also contain a
 12   
     copy of this document.
 13   
 
 14   
  2. Redistributions in binary form must reproduce the
 15   
     above copyright notice, this list of conditions and the
 16   
     following disclaimer in the documentation and/or other
 17   
     materials provided with the distribution.
 18   
 
 19   
  3. The name "groovy" must not be used to endorse or promote
 20   
     products derived from this Software without prior written
 21   
     permission of The Codehaus.  For written permission,
 22   
     please contact info@codehaus.org.
 23   
 
 24   
  4. Products derived from this Software may not be called "groovy"
 25   
     nor may "groovy" appear in their names without prior written
 26   
     permission of The Codehaus. "groovy" is a registered
 27   
     trademark of The Codehaus.
 28   
 
 29   
  5. Due credit should be given to The Codehaus -
 30   
     http://groovy.codehaus.org/
 31   
 
 32   
  THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
 33   
  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 34   
  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 35   
  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 36   
  THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 37   
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 38   
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 39   
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 40   
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 41   
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 42   
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 43   
  OF THE POSSIBILITY OF SUCH DAMAGE.
 44   
 
 45   
  */
 46   
 package groovy.swing;
 47   
 
 48   
 import groovy.lang.Closure;
 49   
 
 50   
 import groovy.model.DefaultTableModel;
 51   
 import groovy.model.ValueHolder;
 52   
 import groovy.model.ValueModel;
 53   
 
 54   
 import groovy.swing.impl.ComponentFacade;
 55   
 import groovy.swing.impl.ContainerFacade;
 56   
 import groovy.swing.impl.DefaultAction;
 57   
 import groovy.swing.impl.Factory;
 58   
 import groovy.swing.impl.Startable;
 59   
 import groovy.swing.impl.TableLayout;
 60   
 import groovy.swing.impl.TableLayoutCell;
 61   
 import groovy.swing.impl.TableLayoutRow;
 62   
 
 63   
 import groovy.util.BuilderSupport;
 64   
 
 65   
 import java.awt.BorderLayout;
 66   
 import java.awt.CardLayout;
 67   
 import java.awt.Component;
 68   
 import java.awt.Container;
 69   
 import java.awt.Dimension;
 70   
 import java.awt.Dialog;
 71   
 import java.awt.FlowLayout;
 72   
 import java.awt.Frame;
 73   
 import java.awt.GridBagConstraints;
 74   
 import java.awt.GridBagLayout;
 75   
 import java.awt.GridLayout;
 76   
 import java.awt.LayoutManager;
 77   
 import java.awt.Window;
 78   
 
 79   
 import java.text.Format;
 80   
 
 81   
 import java.util.ArrayList;
 82   
 import java.util.Collections;
 83   
 import java.util.HashMap;
 84   
 import java.util.HashSet;
 85   
 import java.util.Iterator;
 86   
 import java.util.LinkedList;
 87   
 import java.util.List;
 88   
 import java.util.Map;
 89   
 import java.util.Set;
 90   
 import java.util.Vector;
 91   
 import java.util.logging.Level;
 92   
 import java.util.logging.Logger;
 93   
 
 94   
 import javax.swing.AbstractButton;
 95   
 import javax.swing.Action;
 96   
 import javax.swing.Box;
 97   
 import javax.swing.BoxLayout;
 98   
 import javax.swing.ButtonGroup;
 99   
 import javax.swing.DefaultBoundedRangeModel;
 100   
 import javax.swing.JButton;
 101   
 import javax.swing.JCheckBox;
 102   
 import javax.swing.JCheckBoxMenuItem;
 103   
 import javax.swing.JColorChooser;
 104   
 import javax.swing.JComboBox;
 105   
 import javax.swing.JComponent;
 106   
 import javax.swing.JDesktopPane;
 107   
 import javax.swing.JDialog;
 108   
 import javax.swing.JEditorPane;
 109   
 import javax.swing.JFileChooser;
 110   
 import javax.swing.JFormattedTextField;
 111   
 import javax.swing.JFrame;
 112   
 import javax.swing.JInternalFrame;
 113   
 import javax.swing.JLabel;
 114   
 import javax.swing.JLayeredPane;
 115   
 import javax.swing.JList;
 116   
 import javax.swing.JMenu;
 117   
 import javax.swing.JMenuBar;
 118   
 import javax.swing.JMenuItem;
 119   
 import javax.swing.JOptionPane;
 120   
 import javax.swing.JPanel;
 121   
 import javax.swing.JPasswordField;
 122   
 import javax.swing.JPopupMenu;
 123   
 import javax.swing.JProgressBar;
 124   
 import javax.swing.JRadioButton;
 125   
 import javax.swing.JRadioButtonMenuItem;
 126   
 import javax.swing.JScrollBar;
 127   
 import javax.swing.JScrollPane;
 128   
 import javax.swing.JSeparator;
 129   
 import javax.swing.JSlider;
 130   
 import javax.swing.JSpinner;
 131   
 import javax.swing.JSplitPane;
 132   
 import javax.swing.JTabbedPane;
 133   
 import javax.swing.JTable;
 134   
 import javax.swing.JTextArea;
 135   
 import javax.swing.JTextField;
 136   
 import javax.swing.JTextPane;
 137   
 import javax.swing.JToggleButton;
 138   
 import javax.swing.JToolBar;
 139   
 import javax.swing.JToolTip;
 140   
 import javax.swing.JTree;
 141   
 import javax.swing.JViewport;
 142   
 import javax.swing.JWindow;
 143   
 import javax.swing.KeyStroke;
 144   
 import javax.swing.OverlayLayout;
 145   
 import javax.swing.RootPaneContainer;
 146   
 import javax.swing.SpinnerDateModel;
 147   
 import javax.swing.SpinnerListModel;
 148   
 import javax.swing.SpinnerNumberModel;
 149   
 import javax.swing.SpringLayout;
 150   
 import javax.swing.table.TableColumn;
 151   
 import javax.swing.table.TableModel;
 152   
 
 153   
 import org.codehaus.groovy.runtime.InvokerHelper;
 154   
 
 155   
 /**
 156   
  * A helper class for creating Swing widgets using GroovyMarkup
 157   
  * 
 158   
  * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
 159   
  * @version $Revision: 1.11 $
 160   
  */
 161   
 public class SwingBuilder extends BuilderSupport {
 162   
 
 163   
     private Logger log = Logger.getLogger(getClass().getName());
 164   
     private Map factories = new HashMap();
 165   
     private Object constraints;
 166   
     private Map passThroughNodes = new HashMap();
 167   
     private Map widgets = new HashMap();
 168   
     // tracks all containing windows, for auto-owned dialogs
 169   
     private LinkedList containingWindows = new LinkedList();
 170   
 
 171  0
     public SwingBuilder() {
 172  0
         registerWidgets();
 173   
     }
 174   
 
 175  0
     public Object getProperty(String name) {
 176  0
         Object widget = widgets.get(name);
 177  0
         if (widget == null) {
 178  0
             return super.getProperty(name);
 179   
         }
 180  0
         return widget;
 181   
     }
 182   
 
 183  0
     protected void setParent(Object parent, Object child) {
 184  0
         if (child instanceof Action) {
 185  0
             Action action = (Action) child;
 186  0
             try {
 187  0
                 InvokerHelper.setProperty(parent, "action", action);
 188   
             } catch (RuntimeException re) {
 189   
                 // must not have an action property...
 190   
                 // so we ignore it and go on
 191   
             }
 192  0
             Object keyStroke = action.getValue("KeyStroke");
 193   
             //System.out.println("keystroke: " + keyStroke + " for: " + action);
 194  0
             if (parent instanceof JComponent) {
 195  0
                 JComponent component = (JComponent) parent;
 196  0
                 KeyStroke stroke = null;
 197  0
                 if (keyStroke instanceof String) {
 198  0
                     stroke = KeyStroke.getKeyStroke((String) keyStroke);
 199   
                 }
 200  0
                 else if (keyStroke instanceof KeyStroke) {
 201  0
                     stroke = (KeyStroke) keyStroke;
 202   
                 }
 203  0
                 if (stroke != null) {
 204  0
                     String key = action.toString();
 205  0
                     component.getInputMap().put(stroke, key);
 206  0
                     component.getActionMap().put(key, action);
 207   
                 }
 208   
             }
 209   
         }
 210  0
         else if (child instanceof LayoutManager) {
 211  0
             if (parent instanceof RootPaneContainer) {
 212  0
                 RootPaneContainer rpc = (RootPaneContainer) parent;
 213  0
                 parent = rpc.getContentPane();
 214   
             }
 215  0
             InvokerHelper.setProperty(parent, "layout", child);
 216   
         }
 217  0
         else if (child instanceof JToolTip && parent instanceof JComponent) {
 218  0
             ((JToolTip)child).setComponent((JComponent)parent);
 219   
         }
 220  0
         else if (parent instanceof JTable && child instanceof TableColumn) {
 221  0
             JTable table = (JTable) parent;
 222  0
             TableColumn column = (TableColumn) child;
 223  0
             table.addColumn(column);
 224   
         }
 225  0
         else if (parent instanceof JTabbedPane && child instanceof Component) {
 226  0
             JTabbedPane tabbedPane = (JTabbedPane) parent;
 227  0
             tabbedPane.add((Component)child);
 228   
         } 
 229  0
         else if (child instanceof Window) {
 230   
             // do nothing.  owner of window is set elsewhere, and this 
 231   
             // shouldn't get added to any parent as a child 
 232   
             // if it is a top level component anyway
 233   
         }
 234   
         else { 
 235  0
             Component component = null;
 236  0
             if (child instanceof Component) {
 237  0
                 component = (Component) child;
 238   
             }
 239  0
             else if (child instanceof ComponentFacade) {
 240  0
                 ComponentFacade facade = (ComponentFacade) child;
 241  0
                 component = facade.getComponent();
 242   
             }
 243  0
             if (component != null) {
 244  0
                 if (parent instanceof JFrame && component instanceof JMenuBar) {
 245  0
                     JFrame frame = (JFrame) parent;
 246  0
                     frame.setJMenuBar((JMenuBar) component);
 247   
                 }
 248  0
                 else if (parent instanceof RootPaneContainer) {
 249  0
                     RootPaneContainer rpc = (RootPaneContainer) parent;
 250  0
                     rpc.getContentPane().add(component);
 251   
                 }
 252  0
                 else if (parent instanceof JScrollPane) {
 253  0
                     JScrollPane scrollPane = (JScrollPane) parent;
 254  0
                     if (child instanceof JViewport) {
 255  0
                         scrollPane.setViewport((JViewport)component);
 256   
                     } 
 257   
                     else {
 258  0
                         scrollPane.setViewportView(component);
 259   
                     }
 260   
                 }
 261  0
                 else if (parent instanceof JSplitPane) {
 262  0
                     JSplitPane splitPane = (JSplitPane) parent;
 263  0
                     if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
 264  0
                         if (splitPane.getTopComponent() == null) {
 265  0
                             splitPane.setTopComponent(component);
 266   
                         }
 267   
                         else {
 268  0
                             splitPane.setBottomComponent(component);
 269   
                         }
 270   
                     }
 271   
                     else {
 272  0
                         if (splitPane.getLeftComponent() == null) {
 273  0
                             splitPane.setLeftComponent(component);
 274   
                         }
 275   
                         else {
 276  0
                             splitPane.setRightComponent(component);
 277   
                         }
 278   
                     }
 279   
                 }
 280  0
                 else if (parent instanceof JMenuBar && component instanceof JMenu) {
 281  0
                     JMenuBar menuBar = (JMenuBar) parent;
 282  0
                     menuBar.add((JMenu) component);
 283   
                 }
 284  0
                 else if (parent instanceof Container) {
 285  0
                     Container container = (Container) parent;
 286  0
                     if (constraints != null) {
 287  0
                         container.add(component, constraints);
 288   
                     }
 289   
                     else {
 290  0
                         container.add(component);
 291   
                     }
 292   
                 }
 293  0
                 else if (parent instanceof ContainerFacade) {
 294  0
                     ContainerFacade facade = (ContainerFacade) parent;
 295  0
                     facade.addComponent(component);
 296   
                 }
 297   
             }
 298   
         }
 299   
     }
 300   
 
 301  0
     protected void nodeCompleted(Object parent, Object node) {
 302   
         // set models after the node has been completed
 303  0
         if (node instanceof TableModel && parent instanceof JTable) {
 304  0
             JTable table = (JTable) parent;
 305  0
             TableModel model = (TableModel) node;
 306  0
             table.setModel(model);
 307   
         }
 308  0
         if (node instanceof Startable) {
 309  0
             Startable startable = (Startable) node;
 310  0
             startable.start();
 311   
         }
 312  0
         if (node instanceof Window) {
 313  0
             if (!containingWindows.isEmpty() && containingWindows.getLast() == node) {
 314  0
                 containingWindows.removeLast();
 315   
             }
 316   
         }
 317   
     }
 318   
 
 319  0
     protected Object createNode(Object name) {
 320  0
         return createNode(name, Collections.EMPTY_MAP);
 321   
     }
 322   
 
 323  0
     protected Object createNode(Object name, Object value) {
 324  0
         if (passThroughNodes.containsKey(name) && (value != null) && ((Class)passThroughNodes.get(name)).isAssignableFrom(value.getClass())) {
 325   
             // value may need to go into containing windows list
 326  0
             if (value instanceof Window) {
 327  0
                 containingWindows.add(value);
 328   
             }
 329  0
             return value;
 330   
         }
 331   
         else {
 332  0
             Object widget = createNode(name);
 333  0
             if (widget != null && value instanceof String) {
 334  0
                 InvokerHelper.invokeMethod(widget, "setText", value);
 335   
             }
 336  0
             return widget;
 337   
         }
 338   
     }
 339   
 
 340  0
     protected Object createNode(Object name, Map attributes, Object value) {
 341  0
         if (passThroughNodes.containsKey(name) && (value != null) && ((Class)passThroughNodes.get(name)).isAssignableFrom(value.getClass())) {
 342   
             // value may need to go into containing windows list
 343  0
             if (value instanceof Window) {
 344  0
                 containingWindows.add(value);
 345   
             }
 346  0
             handleWidgetAttributes(value, attributes);
 347  0
             return value;
 348   
         }
 349   
         else { 
 350  0
             Object widget = createNode(name, attributes);
 351  0
             if (widget != null) {
 352  0
                 InvokerHelper.invokeMethod(widget, "setText", value.toString());
 353   
             }
 354  0
             return widget;
 355   
         }
 356   
     }
 357   
     
 358  0
     protected Object createNode(Object name, Map attributes) {
 359  0
         String widgetName = (String) attributes.remove("id");
 360  0
         constraints = attributes.remove("constraints");
 361  0
         Object widget = null;
 362  0
         if (passThroughNodes.containsKey(name)) {
 363  0
             widget = attributes.get(name);
 364  0
             if ((widget != null) && ((Class)passThroughNodes.get(name)).isAssignableFrom(widget.getClass())) {
 365   
                 // value may need to go into containing windows list
 366  0
                 if (widget instanceof Window) {
 367  0
                     containingWindows.add(widget);
 368   
                 }
 369  0
                 attributes.remove(name);
 370   
             }
 371   
             else {
 372  0
                 widget = null;
 373   
             }
 374   
         }
 375  0
         if (widget == null) {
 376  0
             Factory factory = (Factory) factories.get(name);
 377  0
             if (factory != null) {
 378  0
                 try {
 379  0
                     widget = factory.newInstance(attributes);
 380  0
                     if (widgetName != null) {
 381  0
                         widgets.put(widgetName, widget);
 382   
                     }
 383  0
                     if (widget == null) {
 384  0
                         log.log(Level.WARNING, "Factory for name: " + name + " returned null");
 385   
                     }
 386   
                     else {
 387  0
                         if (log.isLoggable(Level.FINE)) {
 388  0
                             log.fine("For name: " + name + " created widget: " + widget);
 389   
                         }
 390   
                     }
 391   
                 }
 392   
                 catch (Exception e) {
 393  0
                     throw new RuntimeException("Failed to create component for" + name + " reason: " + e, e);
 394   
                 }
 395   
             }
 396   
             else {
 397  0
                 log.log(Level.WARNING, "Could not find match for name: " + name);
 398   
             }
 399   
         }
 400  0
         handleWidgetAttributes(widget, attributes);
 401  0
         return widget;
 402   
     }
 403   
 
 404  0
     protected void handleWidgetAttributes(Object widget, Map attributes) {
 405  0
         if (widget != null) {
 406  0
             if (widget instanceof Action) {
 407   
                 /** @todo we could move this custom logic into the MetaClass for Action */
 408  0
                 Action action = (Action) widget;
 409   
 
 410  0
                 Closure closure = (Closure) attributes.remove("closure");
 411  0
                 if (closure != null && action instanceof DefaultAction) {
 412  0
                     DefaultAction defaultAction = (DefaultAction) action;
 413  0
                     defaultAction.setClosure(closure);
 414   
                 }
 415   
 
 416  0
                 Object accel = attributes.remove("accelerator");
 417  0
                 KeyStroke stroke = null;
 418  0
                 if (accel instanceof KeyStroke) {
 419  0
                     stroke = (KeyStroke) accel;
 420  0
                 } else if (accel != null) {
 421  0
                     stroke = KeyStroke.getKeyStroke(accel.toString());
 422   
                 }
 423  0
                 action.putValue(Action.ACCELERATOR_KEY, stroke);
 424   
 
 425  0
                 Object mnemonic = attributes.remove("mnemonic");
 426  0
                 if ((mnemonic != null) && !(mnemonic instanceof Number)) {
 427  0
                     mnemonic = new Integer(mnemonic.toString().charAt(0));
 428   
                 }
 429  0
                 action.putValue(Action.MNEMONIC_KEY, mnemonic);
 430   
 
 431  0
                 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
 432  0
                     Map.Entry entry = (Map.Entry) iter.next();
 433  0
                     String actionName = (String) entry.getKey();
 434   
 
 435   
                     // typically standard Action names start with upper case, so lets upper case it            
 436  0
                     actionName = capitalize(actionName);
 437  0
                     Object value = entry.getValue();
 438   
 
 439  0
                     action.putValue(actionName, value);
 440   
                 }
 441   
 
 442   
             }
 443   
             else {
 444   
                 // some special cases...
 445  0
                 if (attributes.containsKey("buttonGroup")) {
 446  0
                     Object o = attributes.get("buttonGroup");
 447  0
                     if ((o instanceof ButtonGroup) && (widget instanceof AbstractButton)) {
 448  0
                         ((AbstractButton)widget).getModel().setGroup((ButtonGroup)o);
 449  0
                         attributes.remove("buttonGroup");
 450   
                     }
 451   
                 }
 452   
 
 453   
                 // this next statement nd if/else is a workaround until GROOVY-305 is fixed
 454  0
                 Object mnemonic = attributes.remove("mnemonic");
 455  0
                 if ((mnemonic != null) && (mnemonic instanceof Number)) {
 456  0
                     InvokerHelper.setProperty(widget, "mnemonic", new Character((char)((Number)mnemonic).intValue()));
 457   
                 } 
 458  0
                 else if (mnemonic != null) {
 459  0
                     InvokerHelper.setProperty(widget, "mnemonic", new Character(mnemonic.toString().charAt(0)));
 460   
                 } 
 461   
 
 462   
                 // set the properties
 463  0
                 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
 464  0
                     Map.Entry entry = (Map.Entry) iter.next();
 465  0
                     String property = entry.getKey().toString();
 466  0
                     Object value = entry.getValue();
 467  0
                     InvokerHelper.setProperty(widget, property, value);
 468   
                 }
 469   
             }
 470   
         }
 471   
     }
 472   
 
 473  0
     protected String capitalize(String text) {
 474  0
         char ch = text.charAt(0);
 475  0
         if (Character.isUpperCase(ch)) {
 476  0
             return text;
 477   
         }
 478  0
         StringBuffer buffer = new StringBuffer(text.length());
 479  0
         buffer.append(Character.toUpperCase(ch));
 480  0
         buffer.append(text.substring(1));
 481  0
         return buffer.toString();
 482   
     }
 483   
 
 484  0
     protected void registerWidgets() {
 485   
         //
 486   
         // non-widget support classes
 487   
         //
 488  0
         registerBeanFactory("action", DefaultAction.class);
 489  0
         passThroughNodes.put("action", javax.swing.Action.class);
 490  0
         registerBeanFactory("buttonGroup", ButtonGroup.class);
 491  0
         registerFactory("map", new Factory() {
 492  0
             public Object newInstance(Map properties)
 493   
                 throws InstantiationException, InstantiationException, IllegalAccessException {
 494  0
                 return properties;
 495   
             }
 496   
         });
 497   
         // ulimate pass through type
 498  0
         passThroughNodes.put("widget", java.awt.Component.class);
 499   
 
 500   
         //
 501   
         // standalone window classes
 502   
         //
 503  0
         registerFactory("dialog", new Factory() {
 504  0
             public Object newInstance(Map properties)
 505   
                 throws InstantiationException, InstantiationException, IllegalAccessException {
 506  0
                 return createDialog(properties);
 507   
             }
 508   
         });
 509  0
         registerFactory("frame", new Factory() {
 510  0
             public Object newInstance(Map properties)
 511   
                 throws InstantiationException, InstantiationException, IllegalAccessException {
 512  0
                 return createFrame(properties);
 513   
             }
 514   
         });
 515  0
         registerBeanFactory("fileChooser", JFileChooser.class);
 516  0
         registerFactory("frame", new Factory() {
 517  0
             public Object newInstance(Map properties)
 518   
                 throws InstantiationException, InstantiationException, IllegalAccessException {
 519  0
                 return createFrame(properties);
 520   
             }
 521   
         });
 522  0
         registerBeanFactory("optionPane", JOptionPane.class);
 523  0
         registerFactory("window", new Factory() {
 524  0
             public Object newInstance(Map properties)
 525   
                 throws InstantiationException, InstantiationException, IllegalAccessException {
 526  0
                 return createWindow(properties);
 527   
             }
 528   
         });
 529   
         
 530   
         //
 531   
         // widgets
 532   
         //
 533  0
         registerBeanFactory("button", JButton.class);
 534  0
         registerBeanFactory("checkBox", JCheckBox.class);
 535  0
         registerBeanFactory("checkBoxMenuItem", JCheckBoxMenuItem.class);
 536  0
         registerBeanFactory("colorChooser", JColorChooser.class);
 537  0
         registerFactory("comboBox", new Factory() {
 538  0
             public Object newInstance(Map properties)
 539   
                 throws InstantiationException, InstantiationException, IllegalAccessException {
 540  0
                 return createComboBox(properties);
 541   
             }
 542   
         });
 543  0
         registerBeanFactory("desktopPane", JDesktopPane.class);
 544  0
         registerBeanFactory("editorPane", JEditorPane.class);
 545  0
         registerFactory("formattedTextField", new Factory() {
 546  0
             public Object newInstance(Map properties)
 547   
                 throws InstantiationException, InstantiationException, IllegalAccessException {
 548  0
                 return createFormattedTextField(properties);
 549   
             }
 550   
         });
 551  0
         registerBeanFactory("internalFrame", JInternalFrame.class);
 552  0
         registerBeanFactory("label", JLabel.class);
 553  0
         registerBeanFactory("layeredPane", JLayeredPane.class);
 554  0
         registerBeanFactory("list", JList.class);
 555  0
         registerBeanFactory("menu", JMenu.class);
 556  0
         registerBeanFactory("menuBar", JMenuBar.class);
 557  0
         registerBeanFactory("menuItem", JMenuItem.class);
 558  0
         registerBeanFactory("panel", JPanel.class);
 559  0
         registerBeanFactory("passwordField", JPasswordField.class);
 560  0
         registerBeanFactory("popupMenu", JPopupMenu.class);
 561  0
         registerBeanFactory("progressBar", JProgressBar.class);
 562  0
         registerBeanFactory("radioButton", JRadioButton.class);
 563  0
         registerBeanFactory("radioButtonMenuItem", JRadioButtonMenuItem.class);
 564  0
         registerBeanFactory("scrollBar", JScrollBar.class);
 565  0
         registerBeanFactory("scrollPane", JScrollPane.class);
 566  0
         registerBeanFactory("separator", JSeparator.class);
 567  0
         registerBeanFactory("slider", JSlider.class);
 568  0
         registerBeanFactory("spinner", JSpinner.class);
 569  0
         registerFactory("splitPane", new Factory() {
 570  0
             public Object newInstance(Map properties) {
 571  0
                 JSplitPane answer = new JSplitPane();
 572  0
                 answer.setLeftComponent(null);
 573  0
                 answer.setRightComponent(null);
 574  0
                 answer.setTopComponent(null);
 575  0
                 answer.setBottomComponent(null);
 576  0
                 return answer;
 577   
             }
 578   
         });
 579  0
         registerBeanFactory("tabbedPane", JTabbedPane.class);
 580  0
         registerBeanFactory("table", JTable.class);
 581  0
         registerBeanFactory("textArea", JTextArea.class);
 582  0
         registerBeanFactory("textPane", JTextPane.class);
 583  0
         registerBeanFactory("textField", JTextField.class);
 584  0
         registerBeanFactory("toggleButton", JToggleButton.class);
 585  0
         registerBeanFactory("toolBar", JToolBar.class);
 586   
         //registerBeanFactory("tooltip", JToolTip.class); // doens't work, user toolTipText property
 587  0
         registerBeanFactory("tree", JTree.class);
 588  0
         registerBeanFactory("viewport", JViewport.class); // sub class?
 589   
 
 590   
         //
 591   
         // MVC models   
 592   
         //
 593  0
         registerBeanFactory("boundedRangeModel", DefaultBoundedRangeModel.class);
 594   
 
 595   
         // spinner models
 596  0
     registerBeanFactory("spinnerDateModel", SpinnerDateModel.class);
 597  0
         registerBeanFactory("spinnerListModel", SpinnerListModel.class);
 598  0
         registerBeanFactory("spinnerNumberModel", SpinnerNumberModel.class);
 599   
 
 600   
     // table models
 601  0
         registerFactory("tableModel", new Factory() {
 602  0
             public Object newInstance(Map properties) {
 603  0
                 ValueModel model = (ValueModel) properties.remove("model");
 604  0
                 if (model == null) {
 605  0
                     Object list = properties.remove("list");
 606  0
                     if (list == null) {
 607  0
                         list = new ArrayList();
 608   
                     }
 609  0
                     model = new ValueHolder(list);
 610   
                 }
 611  0
                 return new DefaultTableModel(model);
 612   
             }
 613   
         });
 614  0
         passThroughNodes.put("tableModel", javax.swing.table.TableModel.class);
 615   
 
 616  0
         registerFactory("propertyColumn", new Factory() {
 617  0
             public Object newInstance(Map properties) {
 618  0
                 Object current = getCurrent();
 619  0
                 if (current instanceof DefaultTableModel) {
 620  0
                     DefaultTableModel model = (DefaultTableModel) current;
 621  0
                     Object header = properties.remove("header");
 622  0
                     if (header == null) {
 623  0
                         header = "";
 624   
                     }
 625  0
                     String property = (String) properties.remove("propertyName");
 626  0
                     if (property == null) {
 627  0
                         throw new IllegalArgumentException("Must specify a property for a propertyColumn");
 628   
                     }
 629  0
                     Class type = (Class) properties.remove("type");
 630  0
                     if (type == null) {
 631  0
                         type = Object.class;
 632   
                     }
 633  0
                     return model.addPropertyColumn(header, property, type);
 634   
                 }
 635   
                 else {
 636  0
                     throw new RuntimeException("propertyColumn must be a child of a tableModel");
 637   
                 }
 638   
             }
 639   
         });
 640   
 
 641  0
         registerFactory("closureColumn", new Factory() {
 642  0
             public Object newInstance(Map properties) {
 643  0
                 Object current = getCurrent();
 644  0
                 if (current instanceof DefaultTableModel) {
 645  0
                     DefaultTableModel model = (DefaultTableModel) current;
 646  0
                     Object header = properties.remove("header");
 647  0
                     if (header == null) {
 648  0
                         header = "";
 649   
                     }
 650  0
                     Closure readClosure = (Closure) properties.remove("read");
 651  0
                     if (readClosure == null) {
 652  0
                         throw new IllegalArgumentException("Must specify 'read' Closure property for a closureColumn");
 653   
                     }
 654  0
                     Closure writeClosure = (Closure) properties.remove("write");
 655  0
                     Class type = (Class) properties.remove("type");
 656  0
                     if (type == null) {
 657  0
                         type = Object.class;
 658   
                     }
 659  0
                     return model.addClosureColumn(header, readClosure, writeClosure, type);
 660   
                 }
 661   
                 else {
 662  0
                     throw new RuntimeException("propertyColumn must be a child of a tableModel");
 663   
                 }
 664   
             }
 665   
         });
 666   
 
 667   
 
 668   
         //Standard Layouts
 669  0
         registerBeanFactory("borderLayout", BorderLayout.class);
 670  0
         registerBeanFactory("cardLayout", CardLayout.class);
 671  0
         registerBeanFactory("flowLayout", FlowLayout.class);
 672  0
         registerBeanFactory("gridBagLayout", GridBagLayout.class);
 673  0
         registerBeanFactory("gridLayout", GridLayout.class);
 674  0
         registerBeanFactory("overlayLayout", OverlayLayout.class);
 675  0
         registerBeanFactory("springLayout", SpringLayout.class);
 676  0
         registerBeanFactory("gridBagConstarints", GridBagConstraints.class);
 677  0
         registerBeanFactory("gbc", GridBagConstraints.class); // shortcut name
 678   
 
 679   
         // box layout
 680  0
         registerFactory("boxLayout", new Factory() {
 681  0
             public Object newInstance(Map properties)
 682   
                 throws InstantiationException, InstantiationException, IllegalAccessException {
 683  0
                 return createBoxLayout(properties);
 684   
             }
 685   
         });
 686   
 
 687   
         // Box related layout components
 688  0
         registerFactory("hbox", new Factory() {
 689  0
             public Object newInstance(Map properties) {
 690  0
                 return Box.createHorizontalBox();
 691   
             }
 692   
         });
 693  0
         registerFactory("hglue", new Factory() {
 694  0
             public Object newInstance(Map properties) {
 695  0
                 return Box.createHorizontalGlue();
 696   
             }
 697   
         });
 698  0
         registerFactory("hstrut", new Factory() {
 699  0
             public Object newInstance(Map properties) {
 700  0
                 try {
 701  0
                 Object num = properties.remove("width");
 702  0
                 if (num instanceof Number) {
 703  0
                     return Box.createHorizontalStrut(((Number)num).intValue());
 704   
                 } else {
 705  0
                     return Box.createHorizontalStrut(6);
 706   
                 }
 707   
                 } catch (RuntimeException re) {
 708  0
                     re.printStackTrace(System.out);
 709  0
                     throw re;
 710   
                 }
 711   
             }
 712   
         });
 713  0
         registerFactory("vbox", new Factory() {
 714  0
             public Object newInstance(Map properties) {
 715  0
                 return Box.createVerticalBox();
 716   
             }
 717   
         });
 718  0
         registerFactory("vglue", new Factory() {
 719  0
             public Object newInstance(Map properties) {
 720  0
                 return Box.createVerticalGlue();
 721   
             }
 722   
         });
 723  0
         registerFactory("vstrut", new Factory() {
 724  0
             public Object newInstance(Map properties) {
 725  0
                 Object num = properties.remove("height");
 726  0
                 if (num instanceof Number) {
 727  0
                     return Box.createVerticalStrut(((Number)num).intValue());
 728   
                 } else {
 729  0
                     return Box.createVerticalStrut(6);
 730   
                 }
 731   
             }
 732   
         });
 733  0
         registerFactory("glue", new Factory() {
 734  0
             public Object newInstance(Map properties) {
 735  0
                 return Box.createGlue();
 736   
             }
 737   
         });
 738  0
         registerFactory("rigidArea", new Factory() {
 739  0
             public Object newInstance(Map properties) {
 740  0
                 Dimension dim;
 741  0
                 Object o = properties.remove("size");
 742  0
                 if (o instanceof Dimension) {
 743  0
                     dim = (Dimension) o;
 744   
                 } else {
 745  0
                     int w, h;
 746  0
                     o = properties.remove("width");
 747  0
                     w = ((o instanceof Number)) ? ((Number)o).intValue() : 6;
 748  0
                     o = properties.remove("height");
 749  0
                     h = ((o instanceof Number)) ? ((Number)o).intValue() : 6;
 750  0
                     dim = new Dimension(w, h);
 751   
                 }
 752  0
                 return Box.createRigidArea(dim);
 753   
             }
 754   
         });
 755   
         
 756   
         // table layout
 757  0
         registerBeanFactory("tableLayout", TableLayout.class);
 758  0
         registerFactory("tr", new Factory() {
 759  0
             public Object newInstance(Map properties) {
 760  0
                 Object parent = getCurrent();
 761  0
                 if (parent instanceof TableLayout) {
 762  0
                     return new TableLayoutRow((TableLayout) parent);
 763   
                 }
 764   
                 else {
 765  0
                     throw new RuntimeException("'tr' must be within a 'tableLayout'");
 766   
                 }
 767   
             }
 768   
         });
 769  0
         registerFactory("td", new Factory() {
 770  0
             public Object newInstance(Map properties) {
 771  0
                 Object parent = getCurrent();
 772  0
                 if (parent instanceof TableLayoutRow) {
 773  0
                     return new TableLayoutCell((TableLayoutRow) parent);
 774   
                 }
 775   
                 else {
 776  0
                     throw new RuntimeException("'td' must be within a 'tr'");
 777   
                 }
 778   
             }
 779   
         });
 780   
     }
 781   
 
 782  0
     protected Object createBoxLayout(Map properties) {
 783  0
         Object parent = getCurrent();
 784  0
         if (parent instanceof Container) {
 785  0
             Object axisObject = properties.remove("axis");
 786  0
             int axis = 0;
 787  0
             if (axisObject != null) {
 788  0
                 Integer i = (Integer) axisObject;
 789  0
                 axis = i.intValue();
 790   
             }
 791  0
             BoxLayout answer = new BoxLayout((Container) parent, axis);
 792   
             
 793   
             // now lets try set the layout property
 794  0
             InvokerHelper.setProperty(parent, "layout", answer);
 795  0
             return answer;
 796   
         }
 797   
         else {
 798  0
             throw new RuntimeException("Must be nested inside a Container");
 799   
         }
 800   
     }
 801   
 
 802  0
     protected Object createDialog(Map properties) {
 803  0
         JDialog dialog;
 804  0
         Object owner = properties.remove("owner");
 805   
         // if owner not explicit, use the last window type in the list
 806  0
         if ((owner == null) && !containingWindows.isEmpty()) {
 807  0
             owner = containingWindows.getLast();
 808   
         }
 809  0
         if (owner instanceof Frame) {
 810  0
             dialog = new JDialog((Frame) owner);
 811   
         }
 812  0
         else if (owner instanceof Dialog) {
 813  0
             dialog = new JDialog((Dialog) owner);
 814   
         }
 815   
         else {
 816  0
             dialog = new JDialog();
 817   
         }
 818  0
         containingWindows.add(dialog);
 819  0
         return dialog;
 820   
     }
 821   
     
 822   
     /**
 823   
      * Uses 'format," or "value,"  (in order)
 824   
      *
 825   
      */
 826  0
     protected Object createFormattedTextField(Map properties) {
 827  0
         JFormattedTextField ftf;
 828  0
         if (properties.containsKey("format")) {
 829  0
             ftf = new JFormattedTextField((Format) properties.remove("format"));
 830   
         }
 831  0
         else if (properties.containsKey("value")) {
 832  0
             ftf = new JFormattedTextField(properties.remove("value"));
 833   
         }
 834   
         else {
 835  0
             ftf = new JFormattedTextField();
 836   
         }
 837  0
         return ftf;
 838   
     }
 839   
 
 840  0
     protected Object createFrame(Map properties) {
 841  0
         JFrame frame = new JFrame();
 842  0
         containingWindows.add(frame);
 843  0
         return frame;
 844   
     }
 845   
     
 846  0
     protected Object createWindow(Map properties) {
 847  0
         JWindow window;
 848  0
         Object owner = properties.remove("owner");
 849   
         // if owner not explicit, use the last window type in the list
 850  0
         if ((owner == null) && !containingWindows.isEmpty()) {
 851  0
             owner = containingWindows.getLast();
 852   
         }
 853  0
         if (owner instanceof Frame) {
 854  0
             window = new JWindow((Frame) owner);
 855   
         }
 856  0
         else if (owner instanceof Window) {
 857  0
             window = new JWindow((Window) owner);
 858   
         }
 859   
         else {
 860  0
             window = new JWindow();
 861   
         }
 862  0
         containingWindows.add(window);
 863  0
         return window;
 864   
     }
 865   
 
 866  0
     protected Object createComboBox(Map properties) {
 867  0
         Object items = properties.remove("items");
 868  0
         if (items instanceof Vector) {
 869  0
             return new JComboBox((Vector) items);
 870   
         }
 871  0
         else if (items instanceof List) {
 872  0
             List list = (List) items;
 873  0
             return new JComboBox(list.toArray());
 874   
         }
 875  0
         else if (items instanceof Object[]) {
 876  0
             return new JComboBox((Object[]) items);
 877   
         }
 878   
         else {
 879  0
             return new JComboBox();
 880   
         }
 881   
     }
 882   
 
 883  0
     protected void registerBeanFactory(String name, final Class beanClass) {
 884  0
         registerFactory(name, new Factory() {
 885  0
             public Object newInstance(Map properties) throws InstantiationException, IllegalAccessException {
 886  0
                 return beanClass.newInstance();
 887   
             }
 888   
         });
 889   
 
 890   
     }
 891   
 
 892  0
     protected void registerFactory(String name, Factory factory) {
 893  0
         factories.put(name, factory);
 894   
     }
 895   
 }
 896