1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.jguiraffe.gui.platform.swing.builder.components;
17
18 import javax.swing.AbstractButton;
19 import javax.swing.BorderFactory;
20 import javax.swing.ButtonGroup;
21 import javax.swing.Icon;
22 import javax.swing.ImageIcon;
23 import javax.swing.JButton;
24 import javax.swing.JCheckBox;
25 import javax.swing.JComboBox;
26 import javax.swing.JComponent;
27 import javax.swing.JDesktopPane;
28 import javax.swing.JLabel;
29 import javax.swing.JList;
30 import javax.swing.JPanel;
31 import javax.swing.JPasswordField;
32 import javax.swing.JProgressBar;
33 import javax.swing.JRadioButton;
34 import javax.swing.JScrollPane;
35 import javax.swing.JSlider;
36 import javax.swing.JSplitPane;
37 import javax.swing.JTabbedPane;
38 import javax.swing.JTable;
39 import javax.swing.JTextArea;
40 import javax.swing.JTextField;
41 import javax.swing.JToggleButton;
42 import javax.swing.JTree;
43 import javax.swing.ListSelectionModel;
44 import javax.swing.SwingConstants;
45 import javax.swing.border.Border;
46 import javax.swing.border.TitledBorder;
47 import javax.swing.event.TableModelEvent;
48 import javax.swing.event.TableModelListener;
49 import javax.swing.text.JTextComponent;
50 import javax.swing.tree.TreeSelectionModel;
51 import java.awt.Component;
52 import java.awt.Container;
53 import java.awt.Dimension;
54 import java.awt.Font;
55 import java.awt.LayoutManager;
56 import java.awt.font.TextAttribute;
57 import java.lang.reflect.Field;
58 import java.util.HashMap;
59 import java.util.Map;
60
61 import net.sf.jguiraffe.gui.builder.components.ComponentManager;
62 import net.sf.jguiraffe.gui.builder.components.FormBuilderException;
63 import net.sf.jguiraffe.gui.builder.components.FormBuilderRuntimeException;
64 import net.sf.jguiraffe.gui.builder.components.Orientation;
65 import net.sf.jguiraffe.gui.builder.components.WidgetHandler;
66 import net.sf.jguiraffe.gui.builder.components.model.StaticTextData;
67 import net.sf.jguiraffe.gui.builder.components.model.TextIconAlignment;
68 import net.sf.jguiraffe.gui.builder.components.tags.BorderLayoutTag;
69 import net.sf.jguiraffe.gui.builder.components.tags.ButtonLayoutTag;
70 import net.sf.jguiraffe.gui.builder.components.tags.ButtonTag;
71 import net.sf.jguiraffe.gui.builder.components.tags.CheckboxTag;
72 import net.sf.jguiraffe.gui.builder.components.tags.ComboBoxTag;
73 import net.sf.jguiraffe.gui.builder.components.tags.ComponentBaseTag;
74 import net.sf.jguiraffe.gui.builder.components.tags.DesktopPanelTag;
75 import net.sf.jguiraffe.gui.builder.components.tags.FontTag;
76 import net.sf.jguiraffe.gui.builder.components.tags.FormBaseTag;
77 import net.sf.jguiraffe.gui.builder.components.tags.InputComponentTag;
78 import net.sf.jguiraffe.gui.builder.components.tags.LabelTag;
79 import net.sf.jguiraffe.gui.builder.components.tags.ListBoxTag;
80 import net.sf.jguiraffe.gui.builder.components.tags.PanelTag;
81 import net.sf.jguiraffe.gui.builder.components.tags.PasswordFieldTag;
82 import net.sf.jguiraffe.gui.builder.components.tags.PercentLayoutTag;
83 import net.sf.jguiraffe.gui.builder.components.tags.ProgressBarTag;
84 import net.sf.jguiraffe.gui.builder.components.tags.RadioButtonTag;
85 import net.sf.jguiraffe.gui.builder.components.tags.SliderTag;
86 import net.sf.jguiraffe.gui.builder.components.tags.SplitterTag;
87 import net.sf.jguiraffe.gui.builder.components.tags.StaticTextTag;
88 import net.sf.jguiraffe.gui.builder.components.tags.TabbedPaneTag;
89 import net.sf.jguiraffe.gui.builder.components.tags.TextAreaTag;
90 import net.sf.jguiraffe.gui.builder.components.tags.TextFieldTag;
91 import net.sf.jguiraffe.gui.builder.components.tags.TextIconData;
92 import net.sf.jguiraffe.gui.builder.components.tags.ToggleButtonTag;
93 import net.sf.jguiraffe.gui.builder.components.tags.TreeTag;
94 import net.sf.jguiraffe.gui.builder.components.tags.table.TableColumnWidthController;
95 import net.sf.jguiraffe.gui.builder.components.tags.table.TableFormController;
96 import net.sf.jguiraffe.gui.builder.components.tags.table.TableTag;
97 import net.sf.jguiraffe.gui.builder.event.PlatformEventManager;
98 import net.sf.jguiraffe.gui.forms.ComponentHandler;
99 import net.sf.jguiraffe.gui.platform.swing.builder.components.table.SwingTableColumnWidthListener;
100 import net.sf.jguiraffe.gui.platform.swing.builder.components.table.SwingTableModel;
101 import net.sf.jguiraffe.gui.platform.swing.builder.components.table.SwingTableRowHeightUpdater;
102 import net.sf.jguiraffe.gui.platform.swing.builder.components.table.SwingTableSelectionHandler;
103 import net.sf.jguiraffe.gui.platform.swing.builder.event.SwingEventManager;
104 import net.sf.jguiraffe.gui.platform.swing.layout.SwingPercentLayoutAdapter;
105 import net.sf.jguiraffe.gui.platform.swing.layout.SwingSizeHandler;
106 import net.sf.jguiraffe.locators.Locator;
107 import org.apache.commons.jelly.JellyContext;
108 import org.apache.commons.lang.StringUtils;
109 import org.apache.commons.logging.Log;
110 import org.apache.commons.logging.LogFactory;
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public class SwingComponentManager implements ComponentManager
126 {
127
128 public static final String BUILDER_NAME = "SWING_FORM_BUILDER";
129
130
131 private static final TabbedPaneTag.Placement[] TAB_PLACEMENTS = {
132 TabbedPaneTag.Placement.BOTTOM, TabbedPaneTag.Placement.LEFT,
133 TabbedPaneTag.Placement.RIGHT, TabbedPaneTag.Placement.TOP
134 };
135
136
137 private static final int[] SWING_TAB_PLACEMENTS = {
138 JTabbedPane.BOTTOM, JTabbedPane.LEFT, JTabbedPane.RIGHT,
139 JTabbedPane.TOP
140 };
141
142
143
144
145
146 private static final String VAR_SIZE_HANDLER = SwingSizeHandler.class
147 .getName();
148
149
150 private final Log log = LogFactory.getLog(SwingComponentManager.class);
151
152
153 private final Map<String, TextAttribute> textAttributeMapping;
154
155
156 private final SwingTableRowHeightUpdater tableRowHeightUpdater;
157
158
159
160
161 public SwingComponentManager()
162 {
163 this(new SwingTableRowHeightUpdater());
164 }
165
166
167
168
169
170
171
172
173 SwingComponentManager(SwingTableRowHeightUpdater tableRowHeightUpdater)
174 {
175 textAttributeMapping = initTextAttributeMapping();
176 this.tableRowHeightUpdater = tableRowHeightUpdater;
177 }
178
179
180
181
182
183
184
185
186
187
188
189 public void addContainerComponent(Object container, Object component,
190 Object constraints)
191 {
192 Container c = (Container) container;
193 Component comp = (Component) component;
194 if (constraints == null)
195 {
196 c.add(comp);
197 }
198 else
199 {
200 c.add(comp, constraints);
201 }
202 }
203
204
205
206
207
208
209
210
211
212
213 public void setContainerLayout(Object container, Object layout)
214 {
215 ((Container) container).setLayout((LayoutManager) layout);
216 }
217
218
219
220
221
222
223
224
225
226 public PlatformEventManager createEventManager()
227 {
228 return new SwingEventManager();
229 }
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247 public WidgetHandler getWidgetHandlerFor(Object component)
248 {
249 JComponent wrappedComp;
250
251 if (component instanceof JScrollPane)
252 {
253 wrappedComp = (JComponent) ((JScrollPane) component).getViewport()
254 .getView();
255 }
256
257 else if (component instanceof ButtonGroup)
258 {
259 ButtonGroup group = (ButtonGroup) component;
260 if (group.getButtonCount() < 1)
261 {
262 throw new FormBuilderRuntimeException(
263 "ButtonGroup must not be empty!");
264 }
265 return new SwingRadioGroupWidgetHandler(group);
266 }
267 else
268 {
269 wrappedComp = (JComponent) component;
270 }
271
272 return new SwingWidgetHandler(wrappedComp);
273 }
274
275
276
277
278
279
280
281
282
283
284 public Object createLabel(LabelTag tag, boolean create)
285 {
286 if (create)
287 {
288 return null;
289 }
290 else
291 {
292 JLabel label = new JLabel();
293 initLabel(label, tag, tag.getTextIconData());
294 return label;
295 }
296 }
297
298
299
300
301
302
303
304
305
306
307
308 public void linkLabel(Object label, Object component, String text)
309 throws FormBuilderException
310 {
311 JLabel lab = (JLabel) label;
312 lab.setLabelFor((Component) component);
313 if (text != null)
314 {
315 lab.setText(text);
316 }
317 }
318
319
320
321
322
323
324
325
326
327 public Object createIcon(Locator locator) throws FormBuilderException
328 {
329 if (locator == null)
330 {
331 throw new FormBuilderException("Locator for icon must not be null!");
332 }
333
334 if (log.isInfoEnabled())
335 {
336 log.info("Loading icon from " + locator);
337 }
338 return new ImageIcon(locator.getURL());
339 }
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360 public Object createFont(FontTag tag) throws FormBuilderException
361 {
362 Map<TextAttribute, Object> attrs = new HashMap<TextAttribute, Object>();
363
364 handleStandardFontAttributes(tag, attrs);
365 handleExtendedFontAttributes(tag, attrs);
366
367 return new Font(attrs);
368 }
369
370
371
372
373
374
375
376
377
378
379 public Object createPercentLayout(PercentLayoutTag tag)
380 throws FormBuilderException
381 {
382 return new SwingPercentLayoutAdapter(tag.getPercentLayout());
383 }
384
385
386
387
388
389
390
391
392
393
394 public Object createButtonLayout(ButtonLayoutTag tag)
395 throws FormBuilderException
396 {
397 return new SwingPercentLayoutAdapter(tag.getButtonLayout());
398 }
399
400
401
402
403
404
405
406
407
408
409 public Object createBorderLayout(BorderLayoutTag tag)
410 throws FormBuilderException
411 {
412 return new SwingPercentLayoutAdapter(tag.getBorderLayout());
413 }
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428 public Object createPanel(PanelTag tag, boolean create)
429 throws FormBuilderException
430 {
431 if (create)
432 {
433 return null;
434 }
435
436 JPanel panel = new JPanel();
437 initComponent(panel, tag);
438
439 if (tag.isBorder() || tag.getTextData().isDefined())
440 {
441 Border border;
442 if (StringUtils.isNotEmpty(tag.getBorderref()))
443 {
444 border = (Border) tag.getContext().getVariable(
445 tag.getBorderref());
446 if (border == null)
447 {
448 throw new FormBuilderException("Cannot find border "
449 + tag.getBorderref());
450 }
451 }
452 else
453 {
454 border = createDefaultBorder();
455 }
456
457 if (tag.getTextData().isDefined())
458 {
459 border = BorderFactory.createTitledBorder(border, tag
460 .getTextData().getCaption(),
461 TitledBorder.DEFAULT_JUSTIFICATION,
462 TitledBorder.DEFAULT_POSITION,
463 (tag.getTitleFont() != null) ? (Font) tag
464 .getTitleFont() : panel.getFont(), (tag
465 .getColor() != null) ? SwingComponentUtils
466 .logic2SwingColor(tag.getColor()) : panel
467 .getForeground());
468 }
469 panel.setBorder(border);
470 }
471
472 return panel;
473 }
474
475
476
477
478
479
480
481
482
483
484
485 public Object createDesktopPanel(DesktopPanelTag tag, boolean create)
486 throws FormBuilderException
487 {
488 if (create)
489 {
490 return null;
491 }
492
493 else
494 {
495 JDesktopPane pane = new JDesktopPane();
496 initComponent(pane, tag);
497 if (DesktopPanelTag.DragMode.OUTLINE == tag.getDragMode())
498 {
499 pane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
500 }
501 else
502 {
503 pane.setDragMode(JDesktopPane.LIVE_DRAG_MODE);
504 }
505 return pane;
506 }
507 }
508
509
510
511
512
513
514
515
516
517
518
519 public Object createSplitter(SplitterTag tag, boolean create)
520 throws FormBuilderException
521 {
522 if (create)
523 {
524 return null;
525 }
526 else
527 {
528 JSplitPane split = new JSplitPane(
529 tag.getSplitterOrientation() == Orientation.HORIZONTAL
530 ? JSplitPane.HORIZONTAL_SPLIT
531 : JSplitPane.VERTICAL_SPLIT);
532 initComponent(split, tag);
533 split.setResizeWeight(tag.getResizeWeight());
534 if (tag.getPos() > 0)
535 {
536 split.setDividerLocation(tag.getPos());
537 }
538 if (tag.getSize() > 0)
539 {
540 split.setDividerSize(tag.getSize());
541 }
542 split.setLeftComponent((Component) tag.getFirstComponent());
543 split.setRightComponent((Component) tag.getSecondComponent());
544
545 return split;
546 }
547 }
548
549
550
551
552
553
554
555
556
557
558 public ButtonGroup createRadioGroup(Map<String, Object> radios)
559 throws FormBuilderException
560 {
561 if (log.isDebugEnabled())
562 {
563 log.debug("Creating radio group for " + radios.size() + " radios.");
564 }
565 if (radios.isEmpty())
566 {
567 throw new FormBuilderException("Radio group must not be empty!");
568 }
569
570 ButtonGroup group = new ButtonGroup();
571 for (Object comp : radios.values())
572 {
573 group.add((AbstractButton) comp);
574 }
575 return group;
576 }
577
578
579
580
581
582
583
584
585
586
587 public ComponentHandler<Boolean> createButton(ButtonTag tag, boolean create)
588 throws FormBuilderException
589 {
590 if (create)
591 {
592 return null;
593 }
594
595 return createButtonHandler(new JButton(), tag, tag.getTextIconData(),
596 tag.getCommand());
597 }
598
599
600
601
602
603
604
605
606
607
608 public ComponentHandler<Boolean> createToggleButton(ToggleButtonTag tag,
609 boolean create) throws FormBuilderException
610 {
611 if (create)
612 {
613 return null;
614 }
615
616 return createButtonHandler(new JToggleButton(), tag, tag
617 .getTextIconData(), tag.getCommand());
618 }
619
620
621
622
623
624
625
626
627
628
629 public ComponentHandler<String> createTextField(TextFieldTag tag,
630 boolean create) throws FormBuilderException
631 {
632 if (create)
633 {
634 return null;
635 }
636
637 JTextField text = new JTextField();
638 return initTextField(tag, text);
639 }
640
641
642
643
644
645
646
647
648
649
650 public ComponentHandler<String> createTextArea(TextAreaTag tag,
651 boolean create) throws FormBuilderException
652 {
653 if (create)
654 {
655 return null;
656 }
657
658 JTextArea text = new JTextArea();
659 if (tag.getColumns() > 0)
660 {
661 text.setColumns(tag.getColumns());
662 }
663 if (tag.getRows() > 0)
664 {
665 text.setRows(tag.getRows());
666 }
667 if (tag.isWrap())
668 {
669 text.setLineWrap(true);
670 text.setWrapStyleWord(true);
671 }
672
673 initText(text, tag, tag.getMaxlength());
674 SwingSizeHandler sizeHandler = fetchSizeHandler(tag);
675 Object container = tag.findContainer().getContainer();
676 return new SwingTextAreaHandler(text, tag.getPreferredScrollWidth()
677 .toPixel(sizeHandler, container, false), tag
678 .getPreferredScrollHeight().toPixel(sizeHandler, container,
679 true));
680 }
681
682
683
684
685
686
687
688
689
690
691 public ComponentHandler<String> createPasswordField(PasswordFieldTag tag,
692 boolean create) throws FormBuilderException
693 {
694 if (create)
695 {
696 return null;
697 }
698
699 JTextField text = new JPasswordField();
700 return initTextField(tag, text);
701 }
702
703
704
705
706
707
708
709
710
711
712 public ComponentHandler<Boolean> createCheckbox(CheckboxTag tag,
713 boolean create) throws FormBuilderException
714 {
715 if (create)
716 {
717 return null;
718 }
719
720 return createButtonHandler(new JCheckBox(), tag, tag.getTextIconData(),
721 null);
722 }
723
724
725
726
727
728
729
730
731
732
733 public ComponentHandler<Boolean> createRadioButton(RadioButtonTag tag,
734 boolean create) throws FormBuilderException
735 {
736 if (create)
737 {
738 return null;
739 }
740
741 return createButtonHandler(new JRadioButton(), tag, tag
742 .getTextIconData(), null);
743 }
744
745
746
747
748
749
750
751
752
753
754 public ComponentHandler<Object> createComboBox(ComboBoxTag tag,
755 boolean create) throws FormBuilderException
756 {
757 if (create)
758 {
759 return null;
760 }
761
762 JComboBox combo = new JComboBox();
763 initComponent(combo, tag);
764 if (tag.isEditable())
765 {
766 combo.setEditable(true);
767 }
768 return new SwingComboBoxHandler(combo, tag.getListModel());
769 }
770
771
772
773
774
775
776
777
778
779
780 public ComponentHandler<Object> createListBox(ListBoxTag tag, boolean create)
781 throws FormBuilderException
782 {
783 if (create)
784 {
785 return null;
786 }
787
788 JList list = new JList();
789 initComponent(list, tag);
790
791 SwingSizeHandler sizeHandler = fetchSizeHandler(tag);
792 Object container = tag.findContainer().getContainer();
793 int scrollWidth = tag.getPreferredScrollWidth().toPixel(sizeHandler,
794 container, false);
795 int scrollHeight = tag.getPreferredScrollHeight().toPixel(sizeHandler,
796 container, true);
797
798 if (tag.isMulti())
799 {
800 list
801 .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
802 return new SwingMultiListBoxHandler(list, tag.getListModel(),
803 scrollWidth, scrollHeight);
804 }
805 else
806 {
807 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
808 return new SwingListBoxHandler(list, tag.getListModel(),
809 scrollWidth, scrollHeight);
810 }
811 }
812
813
814
815
816
817
818
819
820
821
822 public ComponentHandler<Integer> createTabbedPane(TabbedPaneTag tag,
823 boolean create) throws FormBuilderException
824 {
825 if (create)
826 {
827 return null;
828 }
829 else
830 {
831 JTabbedPane pane = new JTabbedPane();
832 initComponent(pane, tag);
833 for (int i = 0; i < TAB_PLACEMENTS.length; i++)
834 {
835 if (TAB_PLACEMENTS[i].equals(tag.getPlacementValue()))
836 {
837 pane.setTabPlacement(SWING_TAB_PLACEMENTS[i]);
838 break;
839 }
840 }
841
842 int index = 0;
843 for (TabbedPaneTag.TabData tabData : tag.getTabs())
844 {
845 pane.addTab(tabData.getTitle(), (Icon) tabData.getIcon(),
846 (Component) tabData.getComponent(), tabData
847 .getToolTip());
848 pane.setMnemonicAt(index, tabData.getMnemonic());
849 index++;
850 }
851 return new SwingTabbedPaneHandler(pane);
852 }
853 }
854
855
856
857
858
859
860
861
862
863
864 public ComponentHandler<StaticTextData> createStaticText(StaticTextTag tag,
865 boolean create) throws FormBuilderException
866 {
867 if (create)
868 {
869 return null;
870 }
871 else
872 {
873 JLabel label = new JLabel();
874 initLabel(label, tag, tag.getTextIconData());
875 return new SwingStaticTextComponentHandler(label);
876 }
877 }
878
879
880
881
882
883
884
885
886
887
888 public ComponentHandler<Integer> createProgressBar(ProgressBarTag tag,
889 boolean create) throws FormBuilderException
890 {
891 if (create)
892 {
893 return null;
894 }
895
896 else
897 {
898 JProgressBar bar = new JProgressBar();
899 initComponent(bar, tag);
900 bar.setMinimum(tag.getMin().intValue());
901 bar.setMaximum(tag.getMax().intValue());
902 if (tag.getValue() != null)
903 {
904 bar.setValue(tag.getValue().intValue());
905 }
906 if (tag.isAllowText())
907 {
908 bar.setStringPainted(true);
909 bar.setString(tag.getProgressTextData().getCaption());
910 }
911
912 return new SwingProgressBarHandler(bar);
913 }
914 }
915
916
917
918
919
920
921
922
923
924
925 public ComponentHandler<Integer> createSlider(SliderTag tag, boolean create)
926 throws FormBuilderException
927 {
928 if (create)
929 {
930 return null;
931 }
932
933 else
934 {
935 JSlider slider = new JSlider();
936 initComponent(slider, tag);
937 slider.setMinimum(tag.getMin());
938 slider.setMaximum(tag.getMax());
939
940 if (tag.getMinorTicks() > 0)
941 {
942 slider.setMinorTickSpacing(tag.getMinorTicks());
943 }
944 if (tag.getMajorTicks() > 0)
945 {
946 slider.setMajorTickSpacing(tag.getMajorTicks());
947 }
948
949 slider.setPaintLabels(tag.isShowLabels());
950 slider.setPaintTicks(tag.isShowTicks());
951 slider.setOrientation((tag.getSliderOrientation() == Orientation.VERTICAL)
952 ? JSlider.VERTICAL : JSlider.HORIZONTAL);
953
954 return new SwingSliderHandler(slider);
955 }
956 }
957
958
959
960
961
962
963
964
965
966 public ComponentHandler<Object> createTable(TableTag tag, boolean create)
967 throws FormBuilderException
968 {
969 if (create)
970 {
971 return null;
972 }
973
974 else
975 {
976 JTable table = new JTable();
977 SwingTableModel model = new SwingTableModel(tag, table);
978 table.setModel(model);
979 initTableColumnWidths(tag, table);
980 initComponent(table, tag);
981
982 if (tag.getEditorSelectionHandler() == null)
983 {
984 tag.setEditorSelectionHandler(new SwingTableSelectionHandler());
985 }
986
987 if (tag.isMultiSelection())
988 {
989 table
990 .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
991 }
992 else
993 {
994 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
995 }
996
997 if (tag.getSelectionBackgroundColor() != null)
998 {
999 table.setSelectionBackground(SwingComponentUtils
1000 .logic2SwingColor(tag.getSelectionBackgroundColor()));
1001 }
1002 if (tag.getSelectionForegroundColor() != null)
1003 {
1004 table.setSelectionForeground(SwingComponentUtils
1005 .logic2SwingColor(tag.getSelectionForegroundColor()));
1006 }
1007
1008 if (initColumnRenderers(tag.getTableFormController(), model, table))
1009 {
1010 getTableRowHeightUpdater().updateRowHeights(table);
1011 registerRowHeightListener(table, model);
1012 }
1013
1014 SwingSizeHandler sizeHandler = fetchSizeHandler(tag);
1015 Object container = tag.findContainer().getContainer();
1016 SwingTableComponentHandler handler =
1017 new SwingTableComponentHandler(table, tag
1018 .getPreferredScrollWidth().toPixel(sizeHandler,
1019 container, false), tag
1020 .getPreferredScrollHeight().toPixel(sizeHandler,
1021 container, true));
1022 registerTableListener(tag, handler);
1023 return handler;
1024 }
1025 }
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035 public ComponentHandler<Object> createTree(TreeTag tag, boolean create)
1036 throws FormBuilderException
1037 {
1038 if (create)
1039 {
1040 return null;
1041 }
1042
1043 else
1044 {
1045 SwingConfigurationTreeModel model = new SwingConfigurationTreeModel(
1046 tag.getTreeModel());
1047 JTree tree = new JTree(model);
1048 initComponent(tree, tag);
1049
1050 tree.setRootVisible(tag.isRootVisible());
1051 tree.setEditable(tag.isEditable());
1052 tree
1053 .getSelectionModel()
1054 .setSelectionMode(
1055 tag.isMultiSelection() ? TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION
1056 : TreeSelectionModel.SINGLE_TREE_SELECTION);
1057
1058 SwingTreeNodeFormatter formatter = new SwingTreeNodeFormatter();
1059 SwingTreeCellRenderer renderer = new SwingTreeCellRenderer(tag
1060 .getResolvedIconHandler(), tag.getIcons(), formatter);
1061 tree.setCellRenderer(renderer);
1062 tree.setCellEditor(new SwingTreeCellEditor(tree, renderer));
1063
1064 SwingSizeHandler sizeHandler = fetchSizeHandler(tag);
1065 Object container = tag.findContainer().getContainer();
1066 return new SwingTreeComponentHandler(tree, model, tag.getName(),
1067 tag.getPreferredScrollWidth().toPixel(sizeHandler,
1068 container, false), tag.getPreferredScrollHeight()
1069 .toPixel(sizeHandler, container, true));
1070 }
1071 }
1072
1073
1074
1075
1076
1077
1078
1079 protected void initComponent(JComponent component, ComponentBaseTag tag)
1080 {
1081 if (tag.getFont() != null)
1082 {
1083 component.setFont((Font) tag.getFont());
1084 }
1085
1086 if (tag.getBackgroundColor() != null)
1087 {
1088 SwingComponentUtils.setBackgroundColor(component, tag
1089 .getBackgroundColor());
1090 }
1091 if (tag.getForegroundColor() != null)
1092 {
1093 SwingComponentUtils.setForegroundColor(component, tag
1094 .getForegroundColor());
1095 }
1096
1097 if (tag.getToolTipData().isDefined())
1098 {
1099 component.setToolTipText(tag.getToolTipData().getCaption());
1100 }
1101
1102 component.setName(tag.getName());
1103 }
1104
1105
1106
1107
1108
1109
1110
1111
1112 protected void initLabel(JLabel label, ComponentBaseTag tag,
1113 TextIconData data)
1114 {
1115 label.setText(data.getCaption());
1116 if (data.getIcon() != null)
1117 {
1118 label.setIcon((Icon) data.getIcon());
1119 }
1120 if (data.getMnemonic() > 0)
1121 {
1122 label.setDisplayedMnemonic(SwingComponentUtils.toMnemonic(data
1123 .getMnemonic()));
1124 }
1125 label.setHorizontalAlignment(transformAlign(data.getAlignment()));
1126
1127 initComponent(label, tag);
1128 }
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139 protected void initButton(AbstractButton button, InputComponentTag tag,
1140 TextIconData data, String command)
1141 {
1142 initComponent(button, tag);
1143
1144 button.setText(data.getCaption());
1145 if (data.getIcon() != null)
1146 {
1147 button.setIcon((Icon) data.getIcon());
1148 }
1149 if (data.getMnemonic() > 0)
1150 {
1151 button.setMnemonic(SwingComponentUtils.toMnemonic(data
1152 .getMnemonic()));
1153 }
1154 button.setHorizontalAlignment(transformAlign(data.getAlignment()));
1155 if (command != null)
1156 {
1157 button.setActionCommand(command);
1158 }
1159 }
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172 protected ComponentHandler<Boolean> createButtonHandler(
1173 AbstractButton button, InputComponentTag tag, TextIconData data,
1174 String command)
1175 {
1176 initButton(button, tag, data, command);
1177 return new SwingButtonHandler(button);
1178 }
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188 protected void initText(JTextComponent text, InputComponentTag tag,
1189 int maxlen)
1190 {
1191 initComponent(text, tag);
1192 if (maxlen > 0)
1193 {
1194 text.setDocument(new SwingLimitedTextModel(maxlen));
1195 }
1196 }
1197
1198
1199
1200
1201
1202
1203
1204
1205 protected Border createDefaultBorder()
1206 {
1207 return BorderFactory.createEtchedBorder();
1208 }
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221 protected void initTableColumnWidths(TableTag tag, JTable table)
1222 throws FormBuilderException
1223 {
1224 TableFormController tableFormController = tag.getTableFormController();
1225 TableColumnWidthController widthCtrl = tag.getColumnWidthController();
1226 int totalWidth =
1227 tableFormController.calculateFixedColumnWidths(
1228 fetchSizeHandler(tag), tag.findContainer()
1229 .getContainer());
1230
1231 for (int i = 0; i < tag.getColumnCount(); i++)
1232 {
1233 if (!widthCtrl.isPercentWidth(i))
1234 {
1235 table.getColumnModel().getColumn(i)
1236 .setPreferredWidth(widthCtrl.getFixedWidth(i));
1237 }
1238 }
1239
1240 if (widthCtrl.getNumberOfColumnWithPercentWidth() == 0)
1241 {
1242 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
1243 Dimension sz = table.getPreferredScrollableViewportSize();
1244 sz.setSize(totalWidth, sz.getHeight());
1245 table.setPreferredScrollableViewportSize(sz);
1246 }
1247 }
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259 protected void registerTableListener(TableTag tag,
1260 SwingTableComponentHandler handler) throws FormBuilderException
1261 {
1262 if (tag.getColumnWidthController().getNumberOfColumnWithPercentWidth() > 0)
1263 {
1264 SwingTableColumnWidthListener l = new SwingTableColumnWidthListener(
1265 handler.getTable(), tag.getColumnWidthController());
1266 ((JComponent) handler.getOuterComponent()).addComponentListener(l);
1267 handler.getTable().getColumnModel().addColumnModelListener(l);
1268 }
1269 }
1270
1271
1272
1273
1274
1275
1276
1277
1278 static int transformAlign(TextIconAlignment al)
1279 {
1280 int align;
1281 if (TextIconAlignment.RIGHT.equals(al))
1282 {
1283 align = SwingConstants.RIGHT;
1284 }
1285 else if (TextIconAlignment.CENTER.equals(al))
1286 {
1287 align = SwingConstants.CENTER;
1288 }
1289 else
1290 {
1291 align = SwingConstants.LEFT;
1292 }
1293
1294 return align;
1295 }
1296
1297
1298
1299
1300
1301
1302
1303
1304 static TextIconAlignment transformSwingAlign(int al)
1305 {
1306 switch (al)
1307 {
1308 case SwingConstants.RIGHT:
1309 return TextIconAlignment.RIGHT;
1310 case SwingConstants.LEFT:
1311 return TextIconAlignment.LEFT;
1312 case SwingConstants.CENTER:
1313 return TextIconAlignment.CENTER;
1314 default:
1315 throw new IllegalArgumentException("Unknown alignment value: " + al);
1316 }
1317 }
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329 SwingSizeHandler fetchSizeHandler(FormBaseTag tag)
1330 {
1331 JellyContext ctx = tag.getContext();
1332 SwingSizeHandler sizeHandler = (SwingSizeHandler) ctx
1333 .getVariable(VAR_SIZE_HANDLER);
1334
1335 if (sizeHandler == null)
1336 {
1337 sizeHandler = new SwingSizeHandler();
1338 ctx.setVariable(VAR_SIZE_HANDLER, sizeHandler);
1339 }
1340
1341 return sizeHandler;
1342 }
1343
1344
1345
1346
1347
1348
1349 SwingTableRowHeightUpdater getTableRowHeightUpdater()
1350 {
1351 return tableRowHeightUpdater;
1352 }
1353
1354
1355
1356
1357
1358
1359
1360
1361 private ComponentHandler<String> initTextField(TextFieldTag tag,
1362 JTextField text)
1363 {
1364 if (tag.getColumns() > 0)
1365 {
1366 text.setColumns(tag.getColumns());
1367 }
1368 initText(text, tag, tag.getMaxlength());
1369 return new SwingTextHandler(text);
1370 }
1371
1372
1373
1374
1375
1376
1377
1378 private Map<String, TextAttribute> initTextAttributeMapping()
1379 {
1380 log.info("Initializing TextAttribute mapping.");
1381 Map<String, TextAttribute> map = new HashMap<String, TextAttribute>();
1382
1383 for (Field field : TextAttribute.class.getFields())
1384 {
1385 if (field.getType().equals(TextAttribute.class))
1386 {
1387 try
1388 {
1389 map.put(field.getName(), (TextAttribute) field.get(null));
1390 }
1391 catch (IllegalArgumentException e)
1392 {
1393 log.warn("Error when reading field " + field.getName(), e);
1394 }
1395 catch (IllegalAccessException e)
1396 {
1397 log.warn("Error when reading field " + field.getName(), e);
1398 }
1399 }
1400 }
1401
1402 return map;
1403 }
1404
1405
1406
1407
1408
1409
1410
1411
1412 private static void handleStandardFontAttributes(FontTag tag,
1413 Map<TextAttribute, Object> attrs)
1414 {
1415 if (tag.getName() != null)
1416 {
1417 attrs.put(TextAttribute.FAMILY, tag.getName());
1418 }
1419 if (tag.getSize() > 0)
1420 {
1421 attrs.put(TextAttribute.SIZE, Float.valueOf(tag.getSize()));
1422 }
1423 attrs.put(TextAttribute.WEIGHT,
1424 tag.isBold() ? TextAttribute.WEIGHT_BOLD
1425 : TextAttribute.WEIGHT_REGULAR);
1426 attrs.put(TextAttribute.POSTURE,
1427 tag.isItalic() ? TextAttribute.POSTURE_OBLIQUE
1428 : TextAttribute.POSTURE_REGULAR);
1429 }
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439 private void handleExtendedFontAttributes(FontTag tag,
1440 Map<TextAttribute, Object> attrs)
1441 {
1442 for (Map.Entry<?, ?> e : tag.getAttributesMap().entrySet())
1443 {
1444 if (e.getKey() instanceof TextAttribute)
1445 {
1446 attrs.put((TextAttribute) e.getKey(), e.getValue());
1447 }
1448 else
1449 {
1450 TextAttribute ta = textAttributeMapping.get(e.getKey());
1451 if (ta != null)
1452 {
1453 attrs.put(ta, e.getValue());
1454 }
1455 else
1456 {
1457 log.warn("Ignoring font attribute " + e.getKey());
1458 }
1459 }
1460 }
1461 }
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471 private void registerRowHeightListener(final JTable table,
1472 SwingTableModel model)
1473 {
1474 model.addTableModelListener(new TableModelListener()
1475 {
1476 public void tableChanged(TableModelEvent e)
1477 {
1478 if (e.getType() != TableModelEvent.DELETE)
1479 {
1480 getTableRowHeightUpdater().updateRowHeights(table,
1481 e.getFirstRow(), e.getLastRow());
1482 }
1483 }
1484 });
1485 }
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496 private static boolean initColumnRenderers(TableFormController controller,
1497 SwingTableModel tableModel, JTable table)
1498 {
1499 boolean foundCustomRenderer = false;
1500 for (int i = 0; i < controller.getColumnCount(); i++)
1501 {
1502 if (controller.hasRenderer(i))
1503 {
1504 table.getColumnModel().getColumn(i)
1505 .setCellRenderer(tableModel.getRenderer());
1506 foundCustomRenderer = true;
1507 }
1508 }
1509
1510 return foundCustomRenderer;
1511 }
1512 }