KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jgoodies > forms > extras > DefaultFormBuilder


1 /*
2  * Copyright (c) 2003 JGoodies Karsten Lentzsch. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * o Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * o Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * o Neither the name of JGoodies Karsten Lentzsch nor the names of
15  * its contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package com.jgoodies.forms.extras;
32
33 import java.awt.Component JavaDoc;
34 import java.util.ResourceBundle JavaDoc;
35
36 import javax.swing.JComponent JavaDoc;
37 import javax.swing.JLabel JavaDoc;
38 import javax.swing.JPanel JavaDoc;
39
40 import com.jgoodies.forms.factories.FormFactory;
41 import com.jgoodies.forms.layout.ConstantSize;
42 import com.jgoodies.forms.layout.FormLayout;
43 import com.jgoodies.forms.layout.RowSpec;
44
45 /**
46  * Provides a means to build form-oriented panels quickly and consistently
47  * using the {@link FormLayout}. This builder combines frequently used
48  * panel building steps: add a new row, add a label, proceed to the next
49  * data column, then add a component.
50  * <p>
51  * The extra value lies in the <code>#append</code> methods that
52  * append gap rows and component rows if necessary and then add
53  * the given components. They are built upon the superclass behavior
54  * <code>#appendRow</code> and the set of <code>#add</code> methods.
55  * A set of component appenders allows to add a textual label and
56  * associated component in a single step.
57  * <p>
58  * This builder can map resource keys to internationalized (i15d) texts
59  * when creating text labels, titles and titled separators. Therefore
60  * you must specify a <code>ResourceBundle</code> in the constructor.
61  * The builder methods throw an <code>IllegalStateException</code>
62  * if one of the mapping builder methods is invoked and no bundle has been set.
63  * <p>
64  * You can configure the build process by setting a leading column,
65  * enabling the row grouping and by modifying the gaps between normal
66  * lines and between paragraphs. The leading column will be honored
67  * if the cursor proceeds to the next row. All appended components
68  * start in the specified lead column, except appended separators that
69  * span all columns.
70  * <p>
71  * It is temptive to use the DefaultFormBuilder all the time and
72  * to let it add rows automatically. Use a simpler style if it increases
73  * the code readability. Explicit row specifications and cell constraints
74  * make your layout easier to understand - but harder to maintain.
75  * See also the accompanying tutorial sources and the Tips &amp; Tricks
76  * that are part of the Forms documentation.
77  * <p>
78  * Sometimes a form consists of many standardized rows but has a few
79  * rows that require a customization. The DefaultFormBuilder can do everything
80  * that the superclasses {@link com.jgoodies.forms.builder.AbstractFormBuilder}
81  * and {@link com.jgoodies.forms.builder.PanelBuilder} can do;
82  * among other things: appending new rows and moving the cursor.
83  * Again, ask yourself if the DefaultFormBuilder is the appropriate builder.
84  * As a rule of thumb you should have more components than builder commands.
85  * There are different ways to add custom rows. Find below example code
86  * that presents and compares the pros and cons of three approaches.
87  * <p>
88  * This class is not yet part of the binary Forms library;
89  * it comes with the Forms distributions as an extra.
90  * <b>The API is work in progress and may change without notice.</b>
91  * If you want to use this class, you may consider copying it into your codebase.
92  * <p>
93  * <b>Example:</b>
94  * <pre>
95  * public void build() {
96  * FormLayout layout = new FormLayout(
97  * "right:max(40dlu;pref), 3dlu, 80dlu, 7dlu, " // 1st major colum
98  * + "right:max(40dlu;pref), 3dlu, 80dlu", // 2nd major column
99  * ""); // add rows dynamically
100  * DefaultFormBuilder builder = new DefaultFormBuilder(layout);
101  * builder.setDefaultDialogBorder();
102  *
103  * builder.appendSeparator("Flange");
104  *
105  * builder.append("Identifier", identifierField);
106  * builder.nextLine();
107  *
108  * builder.append("PTI [kW]", new JTextField());
109  * builder.append("Power [kW]", new JTextField());
110  *
111  * builder.append("s [mm]", new JTextField());
112  * builder.nextLine();
113  *
114  * builder.appendSeparator("Diameters");
115  *
116  * builder.append("da [mm]", new JTextField());
117  * builder.append("di [mm]", new JTextField());
118  *
119  * builder.append("da2 [mm]", new JTextField());
120  * builder.append("di2 [mm]", new JTextField());
121  *
122  * builder.append("R [mm]", new JTextField());
123  * builder.append("D [mm]", new JTextField());
124  *
125  * builder.appendSeparator("Criteria");
126  *
127  * builder.append("Location", buildLocationComboBox());
128  * builder.append("k-factor", new JTextField());
129  *
130  * builder.appendSeparator("Bolts");
131  *
132  * builder.append("Material", ViewerUIFactory.buildMaterialComboBox());
133  * builder.nextLine();
134  *
135  * builder.append("Numbers", new JTextField());
136  * builder.nextLine();
137  *
138  * builder.append("ds [mm]", new JTextField());
139  * }
140  * </pre>
141  * <p>
142  * <b>Custom Row Example:</b>
143  * <pre>
144  * public JComponent buildPanel() {
145  * initComponents();
146  *
147  * FormLayout layout = new FormLayout(
148  * "right:pref, 3dlu, default:grow",
149  * "");
150  * DefaultFormBuilder builder = new DefaultFormBuilder(layout);
151  * builder.setDefaultDialogBorder();
152  * builder.setRowGroupingEnabled(true);
153  *
154  * CellConstraints cc = new CellConstraints();
155  *
156  * // In this approach, we add a gap and a custom row.
157  * // The advantage of this approach is, that we can express
158  * // the row spec and comment area cell constraints freely.
159  * // The disadvantage is the misalignment of the leading label.
160  * // Also the row's height may be inconsistent with other rows.
161  * builder.appendSeparator("Single Custom Row");
162  * builder.append("Name", name1Field);
163  * builder.appendRow(builder.getLineGapSpec());
164  * builder.appendRow(new RowSpec("top:31dlu")); // Assumes line is 14, gap is 3
165  * builder.nextLine(2);
166  * builder.append("Comment");
167  * builder.add(new JScrollPane(comment1Area),
168  * cc.xy(builder.getColumn(), builder.getRow(), "fill, fill"));
169  * builder.nextLine();
170  *
171  * // In this approach, we append a standard row with gap before it.
172  * // The advantage is, that the leading label is aligned well.
173  * // The disadvantage is that the comment area now spans
174  * // multiple cells and is slightly less flexible.
175  * // Also the row's height may be inconsistent with other rows.
176  * builder.appendSeparator("Standard + Custom Row");
177  * builder.append("Name", name2Field);
178  * builder.append("Comment");
179  * builder.appendRow(new RowSpec("17dlu")); // Assumes line is 14, gap is 3
180  * builder.add(new JScrollPane(comment2Area),
181  * cc.xywh(builder.getColumn(), builder.getRow(), 1, 2));
182  * builder.nextLine(2);
183  *
184  * // In this approach, we append two standard rows with associated gaps.
185  * // The advantage is, that the leading label is aligned well,
186  * // and the height is consistent with other rows.
187  * // The disadvantage is that the comment area now spans
188  * // multiple cells and is slightly less flexible.
189  * builder.appendSeparator("Two Standard Rows");
190  * builder.append("Name", name3Field);
191  * builder.append("Comment");
192  * builder.nextLine();
193  * builder.append("");
194  * builder.nextRow(-2);
195  * builder.add(new JScrollPane(comment3Area),
196  * cc.xywh(builder.getColumn(), builder.getRow(), 1, 3));
197  *
198  * return builder.getPanel();
199  * }
200  * </pre>
201  *
202  * @author Karsten Lentzsch
203  * @version $Revision: 1.3 $
204  * @see com.jgoodies.forms.builder.AbstractFormBuilder
205  * @see com.jgoodies.forms.factories.FormFactory
206  * @see com.jgoodies.forms.layout.FormLayout
207  */

208 public final class DefaultFormBuilder extends I15dPanelBuilder {
209
210     /**
211      * Holds the row specification that is reused to describe
212      * the constant gaps between component lines.
213      */

214     private RowSpec lineGapSpec = FormFactory.LINE_GAP_ROWSPEC;
215
216     /**
217      * Holds the row specification that describes the constant gaps
218      * between paragraphs.
219      */

220     private RowSpec paragraphGapSpec = FormFactory.PARAGRAPH_GAP_ROWSPEC;
221     
222     /**
223      * Holds the offset of the leading column - often 0 or 1.
224      */

225     private int leadingColumnOffset = 0;
226     
227     /**
228      * Determines wether new data rows are being grouped or not.
229      */

230     private boolean rowGroupingEnabled = false;
231     
232
233     // Instance Creation ****************************************************
234

235     /**
236      * Constructs an instance of <code>DefaultFormBuilder</code> for the given
237      * layout.
238      *
239      * @param layout the <code>FormLayout</code> to be used
240      */

241     public DefaultFormBuilder(FormLayout layout) {
242         this(new JPanel JavaDoc(), layout);
243     }
244     
245     /**
246      * Constructs an instance of <code>DefaultFormBuilder</code> for the given
247      * panel and layout.
248      *
249      * @param panel the layout container
250      * @param layout the <code>FormLayout</code> to be used
251      */

252     public DefaultFormBuilder(JPanel JavaDoc panel, FormLayout layout) {
253         this(panel, layout, null);
254     }
255     
256     /**
257      * Constructs an instance of <code>DefaultFormBuilder</code> for the given
258      * layout and resource bundle.
259      *
260      * @param layout the <code>FormLayout</code> to be used
261      * @param bundle the <code>ResourceBundle</code> used to lookup i15d
262      * strings
263      */

264     public DefaultFormBuilder(FormLayout layout, ResourceBundle JavaDoc bundle) {
265         this(new JPanel JavaDoc(), layout, bundle);
266     }
267     
268     /**
269      * Constructs an instance of <code>DefaultFormBuilder</code> for the given
270      * panel, layout and resource bundle.
271      *
272      * @param panel the layout container
273      * @param layout the <code>FormLayout</code> to be used
274      * @param bundle the <code>ResourceBundle</code> used to lookup i15d
275      * strings
276      */

277     public DefaultFormBuilder(JPanel JavaDoc panel, FormLayout layout, ResourceBundle JavaDoc bundle) {
278         super(panel, layout, bundle);
279     }
280     
281     
282     // Settings Gap Sizes ***************************************************
283

284     /**
285      * Sets the size of gaps between component lines using the given
286      * constant size.
287      *
288      * @param lineGapSize the <coide>ConstantSize</code> that describes
289      * the size of the gaps between component lines
290      */

291     public void setLineGapSize(ConstantSize lineGapSize) {
292         RowSpec rowSpec = FormFactory.createGapRowSpec(lineGapSize);
293         this.lineGapSpec = rowSpec.asUnmodifyable();
294     }
295     
296     /**
297      * Returns the row specification that is used to separate component lines.
298      *
299      * @return the <code>RowSpec</code> that is used to separate lines
300      */

301     public RowSpec getLineGapSpec() {
302         return lineGapSpec;
303     }
304     
305     /**
306      * Sets the size of gaps between paragraphs using the given
307      * constant size.
308      *
309      * @param paragraphGapSize the <coide>ConstantSize</code> that describes
310      * the size of the gaps between paragraphs
311      */

312     public void setParagraphGapSize(ConstantSize paragraphGapSize) {
313         RowSpec rowSpec = FormFactory.createGapRowSpec(paragraphGapSize);
314         this.paragraphGapSpec = rowSpec.asUnmodifyable();
315     }
316     
317     /**
318      * Returns the offset of the leading column, often 0 or 1.
319      *
320      * @return the offset of the leading column
321      */

322     public int getLeadingColumnOffset() {
323         return leadingColumnOffset;
324     }
325     
326     /**
327      * Sets the offset of the leading column, often 0 or 1.
328      *
329      * @param columnOffset the new offset of the leading column
330      */

331     public void setLeadingColumnOffset(int columnOffset) {
332         this.leadingColumnOffset = columnOffset;
333     }
334     
335     /**
336      * Returns whether new data rows are being grouped or not.
337      *
338      * @return true indicates grouping enabled, false disabled
339      */

340     public boolean isRowGroupingEnabled() {
341         return rowGroupingEnabled;
342     }
343     
344     /**
345      * Enables or disables the grouping of new data rows.
346      *
347      * @param enabled indicates grouping enabled, false disabled
348      */

349     public void setRowGroupingEnabled(boolean enabled) {
350         rowGroupingEnabled = enabled;
351     }
352     
353
354     // Filling Columns ******************************************************
355

356     /**
357      * Adds a component to the panel using the default constraints.
358      * Proceeds to the next data column.
359      *
360      * @param component the component to add
361      */

362     public void append(Component JavaDoc component) {
363         append(component, 1);
364     }
365     
366     /**
367      * Adds a component to the panel using the default constraints with
368      * the given columnSpan. Proceeds to the next data column.
369      *
370      * @param component the component to append
371      * @param columnSpan the column span used to add
372      */

373     public void append(Component JavaDoc component, int columnSpan) {
374         ensureCursorColumnInGrid();
375         ensureHasGapRow(lineGapSpec);
376         ensureHasComponentLine();
377         
378         setColumnSpan(columnSpan);
379         add(component);
380         setColumnSpan(1);
381         nextColumn(columnSpan + 1);
382     }
383
384     /**
385      * Adds two components to the panel; each component will span a single
386      * data column. Proceeds to the next data column.
387      *
388      * @param c1 the first component to add
389      * @param c2 the second component to add
390      */

391     public void append(Component JavaDoc c1, Component JavaDoc c2) {
392         append(c1);
393         append(c2);
394     }
395
396     /**
397      * Adds three components to the panel; each component will span a single
398      * data column. Proceeds to the next data column.
399      *
400      * @param c1 the first component to add
401      * @param c2 the second component to add
402      * @param c3 the third component to add
403      */

404     public void append(Component JavaDoc c1, Component JavaDoc c2, Component JavaDoc c3) {
405         append(c1);
406         append(c2);
407         append(c3);
408     }
409
410
411     // Appending Labels with optional components ------------------------------
412

413     /**
414      * Adds a text label to the panel and proceeds to the next column.
415      *
416      * @param textWithMnemonic the label's text - may mark a mnemonic
417      * @return the added label
418      */

419     public JLabel JavaDoc append(String JavaDoc textWithMnemonic) {
420         JLabel JavaDoc label = getComponentFactory().createLabel(textWithMnemonic);
421         append(label);
422         return label;
423     }
424
425     /**
426      * Adds a text label and component to the panel.
427      * Then proceeds to the next data column.
428      *
429      * @param textWithMnemonic the label's text - may mark a mnemonic
430      * @param component the component to add
431      * @return the added label
432      */

433     public JLabel JavaDoc append(String JavaDoc textWithMnemonic, Component JavaDoc component) {
434         return append(textWithMnemonic, component, 1);
435     }
436
437     /**
438      * Adds a text label and component to the panel; the component will span
439      * the specified number columns. Proceeds to the next data column.
440      * <p>
441      * The created label is labelling the given component; so the component
442      * gets the focus if the (optional) label mnemonic is pressed.
443      *
444      * @param textWithMnemonic the label's text - may mark a mnemonic
445      * @param c the component to add
446      * @param columnSpan number of columns the component shall span
447      * @return the added label
448      * @see JLabel#setLabelFor
449      */

450     public JLabel JavaDoc append(String JavaDoc textWithMnemonic, Component JavaDoc c, int columnSpan) {
451         JLabel JavaDoc label = append(textWithMnemonic);
452         label.setLabelFor(c);
453         append(c, columnSpan);
454         return label;
455     }
456
457     /**
458      * Adds a text label and two components to the panel; each component
459      * will span a single column. Proceeds to the next data column.
460      *
461      * @param textWithMnemonic the label's text - may mark a mnemonic
462      * @param c1 the first component to add
463      * @param c2 the second component to add
464      * @return the added label
465      */

466     public JLabel JavaDoc append(String JavaDoc textWithMnemonic, Component JavaDoc c1, Component JavaDoc c2) {
467         JLabel JavaDoc label = append(textWithMnemonic, c1);
468         append(c2);
469         return label;
470     }
471
472     /**
473      * Adds a text label and two components to the panel; each component
474      * will span a single column. Proceeds to the next data column.
475      *
476      * @param textWithMnemonic the label's text - may mark a mnemonic
477      * @param c1 the first component to add
478      * @param c2 the second component to add
479      * @param colSpan the column span for the second component
480      */

481     public void append(String JavaDoc textWithMnemonic, Component JavaDoc c1, Component JavaDoc c2, int colSpan) {
482         append(textWithMnemonic, c1);
483         append(c2, colSpan);
484     }
485
486     /**
487      * Adds a text label and three components to the panel; each component
488      * will span a single column. Proceeds to the next data column.
489      *
490      * @param textWithMnemonic the label's text - may mark a mnemonic
491      * @param c1 the first component to add
492      * @param c2 the second component to add
493      * @param c3 the third component to add
494      * @return the added label
495      */

496     public JLabel JavaDoc append(String JavaDoc textWithMnemonic, Component JavaDoc c1, Component JavaDoc c2, Component JavaDoc c3) {
497         JLabel JavaDoc label = append(textWithMnemonic, c1, c2);
498         append(c3);
499         return label;
500     }
501     
502     /**
503      * Adds a text label and four components to the panel; each component
504      * will span a single column. Proceeds to the next data column.
505      *
506      * @param textWithMnemonic the label's text - may mark a mnemonic
507      * @param c1 the first component to add
508      * @param c2 the second component to add
509      * @param c3 the third component to add
510      * @param c4 the fourth component to add
511      * @return the added label
512      */

513     public JLabel JavaDoc append(String JavaDoc textWithMnemonic, Component JavaDoc c1, Component JavaDoc c2, Component JavaDoc c3, Component JavaDoc c4) {
514         JLabel JavaDoc label = append(textWithMnemonic, c1, c2, c3);
515         append(c4);
516         return label;
517     }
518     
519     
520     // Appending internationalized labels with optional components ------------
521

522     /**
523      * Adds an internationalized (i15d) text label to the panel using
524      * the given resource key and proceeds to the next column.
525      *
526      * @param resourceKey the resource key for the the label's text
527      * @return the added label
528      */

529     public JLabel JavaDoc appendI15d(String JavaDoc resourceKey) {
530         return append(getI15dString(resourceKey));
531     }
532
533     /**
534      * Adds an internationalized (i15d) text label to the panel using the given resource key;
535      * then proceeds to the next data column and adds a component with
536      * the given column span. Proceeds to the next data column.
537      *
538      * @param resourceKey the resource key for the text to add
539      * @param c the component to add
540      * @param columnSpan number of columns the component shall span
541      * @return the added label
542      */

543     public JLabel JavaDoc appendI15d(String JavaDoc resourceKey, Component JavaDoc c, int columnSpan) {
544         JLabel JavaDoc label = appendI15d(resourceKey);
545         append(c, columnSpan);
546         return label;
547     }
548
549     /**
550      * Adds an internationalized (i15d) text label and component to the panel.
551      * Then proceeds to the next data column.
552      *
553      * @param resourceKey the resource key for the text to add
554      * @param component the component to add
555      * @return the added label
556      */

557     public JLabel JavaDoc appendI15d(String JavaDoc resourceKey, Component JavaDoc component) {
558         return appendI15d(resourceKey, component, 1);
559     }
560
561     /**
562      * Adds an internationalized (i15d) text label and component to the panel.
563      * Then proceeds to the next data column.
564      * Goes to the next line if the boolean flag is set.
565      *
566      * @param resourceKey the resource key for the text to add
567      * @param component the component to add
568      * @param nextLine true forces a next line
569      * @return the added label
570      */

571     public JLabel JavaDoc appendI15d(String JavaDoc resourceKey, Component JavaDoc component, boolean nextLine) {
572         JLabel JavaDoc label = appendI15d(resourceKey, component, 1);
573         if (nextLine) {
574             nextLine();
575         }
576         return label;
577     }
578
579     /**
580      * Adds an internationalized (i15d) text label and two components to the panel; each component
581      * will span a single column. Proceeds to the next data column.
582      *
583      * @param resourceKey the resource key for the text to add
584      * @param c1 the first component to add
585      * @param c2 the second component to add
586      * @return the added label
587      */

588     public JLabel JavaDoc appendI15d(String JavaDoc resourceKey, Component JavaDoc c1, Component JavaDoc c2) {
589         JLabel JavaDoc label = appendI15d(resourceKey, c1);
590         append(c2);
591         return label;
592     }
593
594     /**
595      * Adds an internationalized (i15d) text label and two components to the panel; each component
596      * will span a single column. Proceeds to the next data column.
597      *
598      * @param resourceKey the resource key for the text to add
599      * @param c1 the first component to add
600      * @param c2 the second component to add
601      * @param colSpan the column span for the second component
602      * @return the added label
603      */

604     public JLabel JavaDoc appendI15d(String JavaDoc resourceKey, Component JavaDoc c1, Component JavaDoc c2, int colSpan) {
605         JLabel JavaDoc label = appendI15d(resourceKey, c1);
606         append(c2, colSpan);
607         return label;
608     }
609
610     /**
611      * Adds an internationalized (i15d) text label and three components to the panel; each component
612      * will span a single column. Proceeds to the next data column.
613      *
614      * @param resourceKey the resource key for the text to add
615      * @param c1 the first component to add
616      * @param c2 the second component to add
617      * @param c3 the third component to add
618      * @return the added label
619      */

620     public JLabel JavaDoc appendI15d(String JavaDoc resourceKey, Component JavaDoc c1, Component JavaDoc c2, Component JavaDoc c3) {
621         JLabel JavaDoc label = appendI15d(resourceKey, c1, c2);
622         append(c3);
623         return label;
624     }
625
626     /**
627      * Adds an internationalized (i15d) text label and four components to the panel;
628      * each component will span a single column. Proceeds to the next data column.
629      *
630      * @param resourceKey the resource key for the text to add
631      * @param c1 the first component to add
632      * @param c2 the second component to add
633      * @param c3 the third component to add
634      * @param c4 the third component to add
635      * @return the added label
636      */

637     public JLabel JavaDoc appendI15d(String JavaDoc resourceKey, Component JavaDoc c1, Component JavaDoc c2, Component JavaDoc c3, Component JavaDoc c4) {
638         JLabel JavaDoc label = appendI15d(resourceKey, c1, c2, c3);
639         append(c4);
640         return label;
641     }
642
643
644     // Adding Titles ----------------------------------------------------------
645

646     /**
647      * Adds a title label to the panel and proceeds to the next column.
648      *
649      * @param textWithMnemonic the label's text - may mark a mnemonic
650      * @return the added title label
651      */

652     public JLabel JavaDoc appendTitle(String JavaDoc textWithMnemonic) {
653         JLabel JavaDoc titleLabel = getComponentFactory().createTitle(textWithMnemonic);
654         append(titleLabel);
655         return titleLabel;
656     }
657      
658     /**
659      * Adds an internationalized title label to the panel and
660      * proceeds to the next column.
661      *
662      * @param resourceKey the resource key for the title's text
663      * @return the added title label
664      */

665     public JLabel JavaDoc appendI15dTitle(String JavaDoc resourceKey) {
666         return appendTitle(getI15dString(resourceKey));
667     }
668      
669
670     // Appending Separators ---------------------------------------------------
671

672     /**
673      * Adds a separator without text that spans all columns.
674      *
675      * @return the added titled separator
676      */

677     public JComponent JavaDoc appendSeparator() {
678         return appendSeparator("");
679     }
680
681     /**
682      * Adds a separator with the given text that spans all columns.
683      *
684      * @param text the separator title text
685      * @return the added titled separator
686      */

687     public JComponent JavaDoc appendSeparator(String JavaDoc text) {
688         ensureCursorColumnInGrid();
689         ensureHasGapRow(paragraphGapSpec);
690         ensureHasComponentLine();
691         
692         setColumn(super.getLeadingColumn());
693         int columnSpan = getColumnCount();
694         setColumnSpan(getColumnCount());
695         JComponent JavaDoc titledSeparator = addSeparator(text);
696         setColumnSpan(1);
697         nextColumn(columnSpan);
698         return titledSeparator;
699     }
700
701     /**
702      * Appends an internationalized titled separator for
703      * the given resource key that spans all columns.
704      *
705      * @param resourceKey the resource key for the separator title's text
706      */

707     public void appendI15dSeparator(String JavaDoc resourceKey) {
708         appendSeparator(getI15dString(resourceKey));
709     }
710     
711
712     // Overriding Superclass Behavior ***************************************
713

714     /**
715      * Returns the leading column. Unlike the superclass we take a
716      * column offset into account.
717      *
718      * @return the leading column
719      */

720     protected int getLeadingColumn() {
721         int column = super.getLeadingColumn();
722         return column + getLeadingColumnOffset() * getColumnIncrementSign();
723     }
724     
725     
726     // Adding Rows **********************************************************
727

728     /**
729      * Ensures that the cursor is in the grid. In case it's beyond the
730      * form's right hand side, the cursor is moved to the leading column
731      * of the next line.
732      */

733     private void ensureCursorColumnInGrid() {
734         if (getColumn() > getColumnCount()) {
735             nextLine();
736         }
737     }
738     
739     /**
740      * Ensures that we have a gap row before the next component row.
741      * Checks if the current row is the given <code>RowSpec</code>
742      * and appends this row spec if necessary.
743      *
744      * @param gapRowSpec the row specification to check for
745      */

746     private void ensureHasGapRow(RowSpec gapRowSpec) {
747         if ((getRow() == 1) || (getRow() <= getRowCount()))
748             return;
749         
750         if (getRow() <= getRowCount()) {
751             RowSpec rowSpec = getCursorRowSpec();
752             if ((rowSpec == gapRowSpec))
753                 return;
754         }
755         appendRow(gapRowSpec);
756         nextLine();
757     }
758     
759     /**
760      * Ensures that the form has a component row. Adds a component row
761      * if the cursor is beyond the form's bottom.
762      */

763     private void ensureHasComponentLine() {
764         if (getRow() <= getRowCount()) return;
765         appendRow(FormFactory.PREF_ROWSPEC);
766         if (isRowGroupingEnabled()) {
767             getLayout().addGroupedRow(getRow());
768         }
769     }
770     
771     /**
772      * Looks up and answers the row specification of the current row.
773      *
774      * @return the row specification of the current row
775      */

776     private RowSpec getCursorRowSpec() {
777         return getLayout().getRowSpec(getRow());
778     }
779
780
781 }
782
Popular Tags