1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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.9 $
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
168 private LinkedList containingWindows = new LinkedList();
169
170 public SwingBuilder() {
171 registerWidgets();
172 }
173
174 protected void setParent(Object parent, Object child) {
175 if (child instanceof Action) {
176 Action action = (Action) child;
177 try {
178 InvokerHelper.setProperty(parent, "action", action);
179 } catch (RuntimeException re) {
180
181
182 }
183 Object keyStroke = action.getValue("KeyStroke");
184
185 if (parent instanceof JComponent) {
186 JComponent component = (JComponent) parent;
187 KeyStroke stroke = null;
188 if (keyStroke instanceof String) {
189 stroke = KeyStroke.getKeyStroke((String) keyStroke);
190 }
191 else if (keyStroke instanceof KeyStroke) {
192 stroke = (KeyStroke) keyStroke;
193 }
194 if (stroke != null) {
195 String key = action.toString();
196 component.getInputMap().put(stroke, key);
197 component.getActionMap().put(key, action);
198 }
199 }
200 }
201 else if (child instanceof LayoutManager) {
202 if (parent instanceof RootPaneContainer) {
203 RootPaneContainer rpc = (RootPaneContainer) parent;
204 parent = rpc.getContentPane();
205 }
206 InvokerHelper.setProperty(parent, "layout", child);
207 }
208 else if (child instanceof JToolTip && parent instanceof JComponent) {
209 ((JToolTip)child).setComponent((JComponent)parent);
210 }
211 else if (parent instanceof JTable && child instanceof TableColumn) {
212 JTable table = (JTable) parent;
213 TableColumn column = (TableColumn) child;
214 table.addColumn(column);
215 }
216 else if (parent instanceof JTabbedPane && child instanceof Component) {
217 JTabbedPane tabbedPane = (JTabbedPane) parent;
218 tabbedPane.add((Component)child);
219 }
220 else if (child instanceof Window) {
221
222
223
224 }
225 else {
226 Component component = null;
227 if (child instanceof Component) {
228 component = (Component) child;
229 }
230 else if (child instanceof ComponentFacade) {
231 ComponentFacade facade = (ComponentFacade) child;
232 component = facade.getComponent();
233 }
234 if (component != null) {
235 if (parent instanceof JFrame && component instanceof JMenuBar) {
236 JFrame frame = (JFrame) parent;
237 frame.setJMenuBar((JMenuBar) component);
238 }
239 else if (parent instanceof RootPaneContainer) {
240 RootPaneContainer rpc = (RootPaneContainer) parent;
241 rpc.getContentPane().add(component);
242 }
243 else if (parent instanceof JScrollPane) {
244 JScrollPane scrollPane = (JScrollPane) parent;
245 if (child instanceof JViewport) {
246 scrollPane.setViewport((JViewport)component);
247 }
248 else {
249 scrollPane.setViewportView(component);
250 }
251 }
252 else if (parent instanceof JSplitPane) {
253 JSplitPane splitPane = (JSplitPane) parent;
254 if (splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
255 if (splitPane.getTopComponent() == null) {
256 splitPane.setTopComponent(component);
257 }
258 else {
259 splitPane.setBottomComponent(component);
260 }
261 }
262 else {
263 if (splitPane.getLeftComponent() == null) {
264 splitPane.setLeftComponent(component);
265 }
266 else {
267 splitPane.setRightComponent(component);
268 }
269 }
270 }
271 else if (parent instanceof JMenuBar && component instanceof JMenu) {
272 JMenuBar menuBar = (JMenuBar) parent;
273 menuBar.add((JMenu) component);
274 }
275 else if (parent instanceof Container) {
276 Container container = (Container) parent;
277 if (constraints != null) {
278 container.add(component, constraints);
279 }
280 else {
281 container.add(component);
282 }
283 }
284 else if (parent instanceof ContainerFacade) {
285 ContainerFacade facade = (ContainerFacade) parent;
286 facade.addComponent(component);
287 }
288 }
289 }
290 }
291
292 protected void nodeCompleted(Object parent, Object node) {
293
294 if (node instanceof TableModel && parent instanceof JTable) {
295 JTable table = (JTable) parent;
296 TableModel model = (TableModel) node;
297 table.setModel(model);
298 }
299 if (node instanceof Startable) {
300 Startable startable = (Startable) node;
301 startable.start();
302 }
303 if (node instanceof Window) {
304 if (!containingWindows.isEmpty() && containingWindows.getLast() == node) {
305 containingWindows.removeLast();
306 }
307 }
308 }
309
310 protected Object createNode(Object name) {
311 return createNode(name, Collections.EMPTY_MAP);
312 }
313
314 protected Object createNode(Object name, Object value) {
315 if (passThroughNodes.containsKey(name) && (value != null) && ((Class)passThroughNodes.get(name)).isAssignableFrom(value.getClass())) {
316
317 if (value instanceof Window) {
318 containingWindows.add(value);
319 }
320 return value;
321 }
322 else {
323 Object widget = createNode(name);
324 if (widget != null && value instanceof String) {
325 InvokerHelper.invokeMethod(widget, "setText", value);
326 }
327 return widget;
328 }
329 }
330
331 protected Object createNode(Object name, Map attributes, Object value) {
332 if (passThroughNodes.containsKey(name) && (value != null) && ((Class)passThroughNodes.get(name)).isAssignableFrom(value.getClass())) {
333
334 if (value instanceof Window) {
335 containingWindows.add(value);
336 }
337 handleWidgetAttributes(value, attributes);
338 return value;
339 }
340 else {
341 Object widget = createNode(name, attributes);
342 if (widget != null) {
343 InvokerHelper.invokeMethod(widget, "setText", value.toString());
344 }
345 return widget;
346 }
347 }
348
349 protected Object createNode(Object name, Map attributes) {
350 constraints = attributes.remove("constraints");
351 Object widget = null;
352 if (passThroughNodes.containsKey(name)) {
353 widget = attributes.get(name);
354 if ((widget != null) && ((Class)passThroughNodes.get(name)).isAssignableFrom(widget.getClass())) {
355
356 if (widget instanceof Window) {
357 containingWindows.add(widget);
358 }
359 attributes.remove(name);
360 }
361 else {
362 widget = null;
363 }
364 }
365 if (widget == null) {
366 Factory factory = (Factory) factories.get(name);
367 if (factory != null) {
368 try {
369 widget = factory.newInstance(attributes);
370 if (widget == null) {
371 log.log(Level.WARNING, "Factory for name: " + name + " returned null");
372 }
373 else {
374 if (log.isLoggable(Level.FINE)) {
375 log.fine("For name: " + name + " created widget: " + widget);
376 }
377 }
378 }
379 catch (Exception e) {
380 throw new RuntimeException("Failed to create component for" + name + " reason: " + e, e);
381 }
382 }
383 else {
384 log.log(Level.WARNING, "Could not find match for name: " + name);
385 }
386 }
387 handleWidgetAttributes(widget, attributes);
388 return widget;
389 }
390
391 protected void handleWidgetAttributes(Object widget, Map attributes) {
392 if (widget != null) {
393 if (widget instanceof Action) {
394 /*** @todo we could move this custom logic into the MetaClass for Action */
395 Action action = (Action) widget;
396
397 Closure closure = (Closure) attributes.remove("closure");
398 if (closure != null && action instanceof DefaultAction) {
399 DefaultAction defaultAction = (DefaultAction) action;
400 defaultAction.setClosure(closure);
401 }
402
403 Object accel = attributes.remove("accelerator");
404 KeyStroke stroke = null;
405 if (accel instanceof KeyStroke) {
406 stroke = (KeyStroke) accel;
407 } else if (accel != null) {
408 stroke = KeyStroke.getKeyStroke(accel.toString());
409 }
410 action.putValue(Action.ACCELERATOR_KEY, stroke);
411
412 Object mnemonic = attributes.remove("mnemonic");
413 if ((mnemonic != null) && !(mnemonic instanceof Number)) {
414 mnemonic = new Integer(mnemonic.toString().charAt(0));
415 }
416 action.putValue(Action.MNEMONIC_KEY, mnemonic);
417
418 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
419 Map.Entry entry = (Map.Entry) iter.next();
420 String actionName = (String) entry.getKey();
421
422
423 actionName = capitalize(actionName);
424 Object value = entry.getValue();
425
426 action.putValue(actionName, value);
427 }
428
429 }
430 else {
431
432 if (attributes.containsKey("buttonGroup")) {
433 Object o = attributes.get("buttonGroup");
434 if ((o instanceof ButtonGroup) && (widget instanceof AbstractButton)) {
435 ((AbstractButton)widget).getModel().setGroup((ButtonGroup)o);
436 attributes.remove("buttonGroup");
437 }
438 }
439
440
441 Object mnemonic = attributes.remove("mnemonic");
442 if ((mnemonic != null) && (mnemonic instanceof Number)) {
443 InvokerHelper.setProperty(widget, "mnemonic", new Character((char)((Number)mnemonic).intValue()));
444 }
445 else if (mnemonic != null) {
446 InvokerHelper.setProperty(widget, "mnemonic", new Character(mnemonic.toString().charAt(0)));
447 }
448
449
450 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
451 Map.Entry entry = (Map.Entry) iter.next();
452 String property = entry.getKey().toString();
453 Object value = entry.getValue();
454 InvokerHelper.setProperty(widget, property, value);
455 }
456 }
457 }
458 }
459
460 protected String capitalize(String text) {
461 char ch = text.charAt(0);
462 if (Character.isUpperCase(ch)) {
463 return text;
464 }
465 StringBuffer buffer = new StringBuffer(text.length());
466 buffer.append(Character.toUpperCase(ch));
467 buffer.append(text.substring(1));
468 return buffer.toString();
469 }
470
471 protected void registerWidgets() {
472
473
474
475 registerBeanFactory("action", DefaultAction.class);
476 passThroughNodes.put("action", javax.swing.Action.class);
477 registerBeanFactory("buttonGroup", ButtonGroup.class);
478 registerFactory("map", new Factory() {
479 public Object newInstance(Map properties)
480 throws InstantiationException, InstantiationException, IllegalAccessException {
481 return properties;
482 }
483 });
484
485 passThroughNodes.put("widget", java.awt.Component.class);
486
487
488
489
490 registerFactory("dialog", new Factory() {
491 public Object newInstance(Map properties)
492 throws InstantiationException, InstantiationException, IllegalAccessException {
493 return createDialog(properties);
494 }
495 });
496 registerFactory("frame", new Factory() {
497 public Object newInstance(Map properties)
498 throws InstantiationException, InstantiationException, IllegalAccessException {
499 return createFrame(properties);
500 }
501 });
502 registerBeanFactory("fileChooser", JFileChooser.class);
503 registerFactory("frame", new Factory() {
504 public Object newInstance(Map properties)
505 throws InstantiationException, InstantiationException, IllegalAccessException {
506 return createFrame(properties);
507 }
508 });
509 registerBeanFactory("optionPane", JOptionPane.class);
510 registerFactory("window", new Factory() {
511 public Object newInstance(Map properties)
512 throws InstantiationException, InstantiationException, IllegalAccessException {
513 return createWindow(properties);
514 }
515 });
516
517
518
519
520 registerBeanFactory("button", JButton.class);
521 registerBeanFactory("checkBox", JCheckBox.class);
522 registerBeanFactory("checkBoxMenuItem", JCheckBoxMenuItem.class);
523 registerBeanFactory("colorChooser", JColorChooser.class);
524 registerFactory("comboBox", new Factory() {
525 public Object newInstance(Map properties)
526 throws InstantiationException, InstantiationException, IllegalAccessException {
527 return createComboBox(properties);
528 }
529 });
530 registerBeanFactory("desktopPane", JDesktopPane.class);
531 registerBeanFactory("editorPane", JEditorPane.class);
532 registerFactory("formattedTextField", new Factory() {
533 public Object newInstance(Map properties)
534 throws InstantiationException, InstantiationException, IllegalAccessException {
535 return createFormattedTextField(properties);
536 }
537 });
538 registerBeanFactory("internalFrame", JInternalFrame.class);
539 registerBeanFactory("label", JLabel.class);
540 registerBeanFactory("layeredPane", JLayeredPane.class);
541 registerBeanFactory("list", JList.class);
542 registerBeanFactory("menu", JMenu.class);
543 registerBeanFactory("menuBar", JMenuBar.class);
544 registerBeanFactory("menuItem", JMenuItem.class);
545 registerBeanFactory("panel", JPanel.class);
546 registerBeanFactory("passwordField", JPasswordField.class);
547 registerBeanFactory("popupMenu", JPopupMenu.class);
548 registerBeanFactory("progressBar", JProgressBar.class);
549 registerBeanFactory("radioButton", JRadioButton.class);
550 registerBeanFactory("radioButtonMenuItem", JRadioButtonMenuItem.class);
551 registerBeanFactory("scrollBar", JScrollBar.class);
552 registerBeanFactory("scrollPane", JScrollPane.class);
553 registerBeanFactory("separator", JSeparator.class);
554 registerBeanFactory("slider", JSlider.class);
555 registerBeanFactory("spinner", JSpinner.class);
556 registerFactory("splitPane", new Factory() {
557 public Object newInstance(Map properties) {
558 JSplitPane answer = new JSplitPane();
559 answer.setLeftComponent(null);
560 answer.setRightComponent(null);
561 answer.setTopComponent(null);
562 answer.setBottomComponent(null);
563 return answer;
564 }
565 });
566 registerBeanFactory("tabbedPane", JTabbedPane.class);
567 registerBeanFactory("table", JTable.class);
568 registerBeanFactory("textArea", JTextArea.class);
569 registerBeanFactory("textPane", JTextPane.class);
570 registerBeanFactory("textField", JTextField.class);
571 registerBeanFactory("toggleButton", JToggleButton.class);
572 registerBeanFactory("toolBar", JToolBar.class);
573
574 registerBeanFactory("tree", JTree.class);
575 registerBeanFactory("viewport", JViewport.class);
576
577
578
579
580 registerBeanFactory("boundedRangeModel", DefaultBoundedRangeModel.class);
581
582
583 registerBeanFactory("spinnerDateModel", SpinnerDateModel.class);
584 registerBeanFactory("spinnerListModel", SpinnerListModel.class);
585 registerBeanFactory("spinnerNumberModel", SpinnerNumberModel.class);
586
587
588 registerFactory("tableModel", new Factory() {
589 public Object newInstance(Map properties) {
590 ValueModel model = (ValueModel) properties.remove("model");
591 if (model == null) {
592 Object list = properties.remove("list");
593 if (list == null) {
594 list = new ArrayList();
595 }
596 model = new ValueHolder(list);
597 }
598 return new DefaultTableModel(model);
599 }
600 });
601 passThroughNodes.put("tableModel", javax.swing.table.TableModel.class);
602
603 registerFactory("propertyColumn", new Factory() {
604 public Object newInstance(Map properties) {
605 Object current = getCurrent();
606 if (current instanceof DefaultTableModel) {
607 DefaultTableModel model = (DefaultTableModel) current;
608 Object header = properties.remove("header");
609 if (header == null) {
610 header = "";
611 }
612 String property = (String) properties.remove("propertyName");
613 if (property == null) {
614 throw new IllegalArgumentException("Must specify a property for a propertyColumn");
615 }
616 Class type = (Class) properties.remove("type");
617 if (type == null) {
618 type = Object.class;
619 }
620 return model.addPropertyColumn(header, property, type);
621 }
622 else {
623 throw new RuntimeException("propertyColumn must be a child of a tableModel");
624 }
625 }
626 });
627
628 registerFactory("closureColumn", new Factory() {
629 public Object newInstance(Map properties) {
630 Object current = getCurrent();
631 if (current instanceof DefaultTableModel) {
632 DefaultTableModel model = (DefaultTableModel) current;
633 Object header = properties.remove("header");
634 if (header == null) {
635 header = "";
636 }
637 Closure readClosure = (Closure) properties.remove("read");
638 if (readClosure == null) {
639 throw new IllegalArgumentException("Must specify 'read' Closure property for a closureColumn");
640 }
641 Closure writeClosure = (Closure) properties.remove("write");
642 Class type = (Class) properties.remove("type");
643 if (type == null) {
644 type = Object.class;
645 }
646 return model.addClosureColumn(header, readClosure, writeClosure, type);
647 }
648 else {
649 throw new RuntimeException("propertyColumn must be a child of a tableModel");
650 }
651 }
652 });
653
654
655
656 registerBeanFactory("borderLayout", BorderLayout.class);
657 registerBeanFactory("cardLayout", CardLayout.class);
658 registerBeanFactory("flowLayout", FlowLayout.class);
659 registerBeanFactory("gridBagLayout", GridBagLayout.class);
660 registerBeanFactory("gridLayout", GridLayout.class);
661 registerBeanFactory("overlayLayout", OverlayLayout.class);
662 registerBeanFactory("springLayout", SpringLayout.class);
663 registerBeanFactory("gridBagConstarints", GridBagConstraints.class);
664 registerBeanFactory("gbc", GridBagConstraints.class);
665
666
667 registerFactory("boxLayout", new Factory() {
668 public Object newInstance(Map properties)
669 throws InstantiationException, InstantiationException, IllegalAccessException {
670 return createBoxLayout(properties);
671 }
672 });
673
674
675 registerFactory("hbox", new Factory() {
676 public Object newInstance(Map properties) {
677 return Box.createHorizontalBox();
678 }
679 });
680 registerFactory("hglue", new Factory() {
681 public Object newInstance(Map properties) {
682 return Box.createHorizontalGlue();
683 }
684 });
685 registerFactory("hstrut", new Factory() {
686 public Object newInstance(Map properties) {
687 try {
688 Object num = properties.remove("width");
689 if (num instanceof Number) {
690 return Box.createHorizontalStrut(((Number)num).intValue());
691 } else {
692 return Box.createHorizontalStrut(6);
693 }
694 } catch (RuntimeException re) {
695 re.printStackTrace(System.out);
696 throw re;
697 }
698 }
699 });
700 registerFactory("vbox", new Factory() {
701 public Object newInstance(Map properties) {
702 return Box.createVerticalBox();
703 }
704 });
705 registerFactory("vglue", new Factory() {
706 public Object newInstance(Map properties) {
707 return Box.createVerticalGlue();
708 }
709 });
710 registerFactory("vstrut", new Factory() {
711 public Object newInstance(Map properties) {
712 Object num = properties.remove("height");
713 if (num instanceof Number) {
714 return Box.createVerticalStrut(((Number)num).intValue());
715 } else {
716 return Box.createVerticalStrut(6);
717 }
718 }
719 });
720 registerFactory("glue", new Factory() {
721 public Object newInstance(Map properties) {
722 return Box.createGlue();
723 }
724 });
725 registerFactory("rigidArea", new Factory() {
726 public Object newInstance(Map properties) {
727 Dimension dim;
728 Object o = properties.remove("size");
729 if (o instanceof Dimension) {
730 dim = (Dimension) o;
731 } else {
732 int w, h;
733 o = properties.remove("width");
734 w = ((o instanceof Number)) ? ((Number)o).intValue() : 6;
735 o = properties.remove("height");
736 h = ((o instanceof Number)) ? ((Number)o).intValue() : 6;
737 dim = new Dimension(w, h);
738 }
739 return Box.createRigidArea(dim);
740 }
741 });
742
743
744 registerBeanFactory("tableLayout", TableLayout.class);
745 registerFactory("tr", new Factory() {
746 public Object newInstance(Map properties) {
747 Object parent = getCurrent();
748 if (parent instanceof TableLayout) {
749 return new TableLayoutRow((TableLayout) parent);
750 }
751 else {
752 throw new RuntimeException("'tr' must be within a 'tableLayout'");
753 }
754 }
755 });
756 registerFactory("td", new Factory() {
757 public Object newInstance(Map properties) {
758 Object parent = getCurrent();
759 if (parent instanceof TableLayoutRow) {
760 return new TableLayoutCell((TableLayoutRow) parent);
761 }
762 else {
763 throw new RuntimeException("'td' must be within a 'tr'");
764 }
765 }
766 });
767 }
768
769 protected Object createBoxLayout(Map properties) {
770 Object parent = getCurrent();
771 if (parent instanceof Container) {
772 Object axisObject = properties.remove("axis");
773 int axis = 0;
774 if (axisObject != null) {
775 Integer i = (Integer) axisObject;
776 axis = i.intValue();
777 }
778 BoxLayout answer = new BoxLayout((Container) parent, axis);
779
780
781 InvokerHelper.setProperty(parent, "layout", answer);
782 return answer;
783 }
784 else {
785 throw new RuntimeException("Must be nested inside a Container");
786 }
787 }
788
789 protected Object createDialog(Map properties) {
790 JDialog dialog;
791 Object owner = properties.remove("owner");
792
793 if ((owner == null) && !containingWindows.isEmpty()) {
794 owner = containingWindows.getLast();
795 }
796 if (owner instanceof Frame) {
797 dialog = new JDialog((Frame) owner);
798 }
799 else if (owner instanceof Dialog) {
800 dialog = new JDialog((Dialog) owner);
801 }
802 else {
803 dialog = new JDialog();
804 }
805 containingWindows.add(dialog);
806 return dialog;
807 }
808
809 /***
810 * Uses 'format," or "value," (in order)
811 *
812 */
813 protected Object createFormattedTextField(Map properties) {
814 JFormattedTextField ftf;
815 if (properties.containsKey("format")) {
816 ftf = new JFormattedTextField((Format) properties.remove("format"));
817 }
818 else if (properties.containsKey("value")) {
819 ftf = new JFormattedTextField(properties.remove("value"));
820 }
821 else {
822 ftf = new JFormattedTextField();
823 }
824 return ftf;
825 }
826
827 protected Object createFrame(Map properties) {
828 JFrame frame = new JFrame();
829 containingWindows.add(frame);
830 return frame;
831 }
832
833 protected Object createWindow(Map properties) {
834 JWindow window;
835 Object owner = properties.remove("owner");
836
837 if ((owner == null) && !containingWindows.isEmpty()) {
838 owner = containingWindows.getLast();
839 }
840 if (owner instanceof Frame) {
841 window = new JWindow((Frame) owner);
842 }
843 else if (owner instanceof Window) {
844 window = new JWindow((Window) owner);
845 }
846 else {
847 window = new JWindow();
848 }
849 containingWindows.add(window);
850 return window;
851 }
852
853 protected Object createComboBox(Map properties) {
854 Object items = properties.remove("items");
855 if (items instanceof Vector) {
856 return new JComboBox((Vector) items);
857 }
858 else if (items instanceof List) {
859 List list = (List) items;
860 return new JComboBox(list.toArray());
861 }
862 else if (items instanceof Object[]) {
863 return new JComboBox((Object[]) items);
864 }
865 else {
866 return new JComboBox();
867 }
868 }
869
870 protected void registerBeanFactory(String name, final Class beanClass) {
871 registerFactory(name, new Factory() {
872 public Object newInstance(Map properties) throws InstantiationException, IllegalAccessException {
873 return beanClass.newInstance();
874 }
875 });
876
877 }
878
879 protected void registerFactory(String name, Factory factory) {
880 factories.put(name, factory);
881 }
882 }