001: /*
002: * Copyright (c) 2002-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.forms.factories;
032:
033: import com.jgoodies.forms.layout.ColumnSpec;
034: import com.jgoodies.forms.layout.ConstantSize;
035: import com.jgoodies.forms.layout.FormLayout;
036: import com.jgoodies.forms.layout.RowSpec;
037: import com.jgoodies.forms.layout.Sizes;
038: import com.jgoodies.forms.util.LayoutStyle;
039:
040: /**
041: * A factory that creates instances of FormLayout for frequently used
042: * form layouts. It makes form creation easier and more consistent.<p>
043: *
044: * <strong>I consider removing the <code>FormLayout</code> factory methods.
045: * These seem to be less usefull and may lead to poor layout readability.
046: * If you want to use these methods, you may consider copying them
047: * to your codebase.</strong><p>
048: *
049: * The forms are described by major and minor columns. Major columns
050: * consist of a leading label and a set of related components, for example: a
051: * label plus textfield, or label plus textfield plus button. The component
052: * part of a major column is divided into minor columns as shown in this
053: * layout:
054: * <pre>
055: * <- major column 1 -> <- major column 2 ->
056: * label1 textfield1a textfield1b label2 textfield2a textfield2b
057: * label3 textfield3a textfield3b label4 textfield4
058: * label5 textfield5 label6 textfield6
059: * </pre><p>
060: *
061: * Many forms use 1, 2, 3 or 4 major columns, which in turn are often split
062: * into 1, 2, 3 or 4 minor columns.
063: *
064: * @author Karsten Lentzsch
065: * @version $Revision: 1.3 $
066: *
067: * @see com.jgoodies.forms.layout.FormLayout
068: * @see ColumnSpec
069: */
070: public final class FormFactory {
071:
072: private FormFactory() {
073: // Suppresses default constructor, ensuring non-instantiability.
074: }
075:
076: // Frequently used Column Specifications ********************************
077:
078: /**
079: * An unmodifyable <code>ColumnSpec</code> that determines its width by
080: * computing the maximum of all column component minimum widths.
081: *
082: * @see #PREF_COLSPEC
083: * @see #DEFAULT_COLSPEC
084: */
085: public static final ColumnSpec MIN_COLSPEC = new ColumnSpec(
086: Sizes.MINIMUM);
087:
088: /**
089: * An unmodifyable <code>ColumnSpec</code> that determines its width by
090: * computing the maximum of all column component preferred widths.
091: *
092: * @see #MIN_COLSPEC
093: * @see #DEFAULT_COLSPEC
094: */
095: public static final ColumnSpec PREF_COLSPEC = new ColumnSpec(
096: Sizes.PREFERRED);
097:
098: /**
099: * An unmodifyable <code>ColumnSpec</code> that determines its preferred
100: * width by computing the maximum of all column component preferred widths
101: * and its minimum width by computing all column component minimum widths.<p>
102: *
103: * Useful to let a column shrink from preferred width to minimum width
104: * if the container space gets scarce.
105: *
106: * @see #MIN_COLSPEC
107: * @see #PREF_COLSPEC
108: */
109: public static final ColumnSpec DEFAULT_COLSPEC = new ColumnSpec(
110: Sizes.DEFAULT);
111:
112: /**
113: * An unmodifyable <code>ColumnSpec</code> that has an initial width
114: * of 0 pixels and that grows. Useful to describe <em>glue</em> columns
115: * that fill the space between other columns.
116: *
117: * @see #GLUE_ROWSPEC
118: */
119: public static final ColumnSpec GLUE_COLSPEC = new ColumnSpec(
120: ColumnSpec.DEFAULT, Sizes.ZERO, ColumnSpec.DEFAULT_GROW);
121:
122: // Layout Style Dependent Column Specs ***********************************
123:
124: /**
125: * Describes a logical horizontal gap between a label and an associated
126: * component. Useful for builders that automatically fill a grid with labels
127: * and components.<p>
128: *
129: * <strong>Note:</strong> In a future version this constant will likely
130: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
131: *
132: * @since 1.0.3
133: */
134: public static final ColumnSpec LABEL_COMPONENT_GAP_COLSPEC = createGapColumnSpec(LayoutStyle
135: .getCurrent().getLabelComponentPadX());
136:
137: /**
138: * Describes a logical horizontal gap between two related components.
139: * For example the <em>OK</em> and <em>Cancel</em> buttons are considered
140: * related.<p>
141: *
142: * <strong>Note:</strong> In a future version this constant will likely
143: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
144: *
145: * @see #UNRELATED_GAP_COLSPEC
146: */
147: public static final ColumnSpec RELATED_GAP_COLSPEC = createGapColumnSpec(LayoutStyle
148: .getCurrent().getRelatedComponentsPadX());
149:
150: /**
151: * Describes a logical horizontal gap between two unrelated components.<p>
152: *
153: * <strong>Note:</strong> In a future version this constant will likely
154: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
155: *
156: * @see #RELATED_GAP_COLSPEC
157: */
158: public static final ColumnSpec UNRELATED_GAP_COLSPEC = createGapColumnSpec(LayoutStyle
159: .getCurrent().getUnrelatedComponentsPadX());
160:
161: /**
162: * Describes a logical horizontal column for a fixed size button. This spec
163: * honors the current layout style's default button minimum width.<p>
164: *
165: * <strong>Note:</strong> In a future version this constant will likely
166: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
167: *
168: * @see #GROWING_BUTTON_COLSPEC
169: */
170: public static final ColumnSpec BUTTON_COLSPEC = new ColumnSpec(
171: Sizes.bounded(Sizes.PREFERRED, LayoutStyle.getCurrent()
172: .getDefaultButtonWidth(), null));
173:
174: /**
175: * Describes a logical horizontal column for a growing button. This spec
176: * does <em>not</em> use the layout style's default button minimum width.<p>
177: *
178: * <strong>Note:</strong> In a future version this constant will likely
179: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
180: *
181: * @see #BUTTON_COLSPEC
182: */
183: public static final ColumnSpec GROWING_BUTTON_COLSPEC = new ColumnSpec(
184: ColumnSpec.DEFAULT, BUTTON_COLSPEC.getSize(),
185: ColumnSpec.DEFAULT_GROW);
186:
187: // Frequently used Row Specifications ***********************************
188:
189: /**
190: * An unmodifyable <code>RowSpec</code> that determines its height by
191: * computing the maximum of all column component minimum heights.
192: *
193: * @see #PREF_ROWSPEC
194: * @see #DEFAULT_ROWSPEC
195: */
196: public static final RowSpec MIN_ROWSPEC = new RowSpec(Sizes.MINIMUM);
197:
198: /**
199: * An unmodifyable <code>RowSpec</code> that determines its height by
200: * computing the maximum of all column component preferred heights.
201: *
202: * @see #MIN_ROWSPEC
203: * @see #DEFAULT_ROWSPEC
204: */
205: public static final RowSpec PREF_ROWSPEC = new RowSpec(
206: Sizes.PREFERRED);
207:
208: /**
209: * An unmodifyable <code>RowSpec</code> that determines its preferred
210: * height by computing the maximum of all column component preferred heights
211: * and its minimum height by computing all column component minimum heights.<p>
212: *
213: * Useful to let a column shrink from preferred height to minimum height
214: * if the container space gets scarce.
215: *
216: * @see #MIN_COLSPEC
217: * @see #PREF_COLSPEC
218: */
219: public static final RowSpec DEFAULT_ROWSPEC = new RowSpec(
220: Sizes.DEFAULT);
221:
222: /**
223: * An unmodifyable <code>RowSpec</code> that has an initial height
224: * of 0 pixels and that grows. Useful to describe <em>glue</em> rows
225: * that fill the space between other rows.
226: *
227: * @see #GLUE_COLSPEC
228: */
229: public static final RowSpec GLUE_ROWSPEC = new RowSpec(
230: RowSpec.DEFAULT, Sizes.ZERO, RowSpec.DEFAULT_GROW);
231:
232: // Layout Style Dependent Row Specs *************************************
233:
234: /**
235: * Describes a logical vertzical gap between two related components.
236: * For example the <em>OK</em> and <em>Cancel</em> buttons are considered
237: * related.<p>
238: *
239: * <strong>Note:</strong> In a future version this constant will likely
240: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
241: *
242: * @see #UNRELATED_GAP_ROWSPEC
243: */
244: public static final RowSpec RELATED_GAP_ROWSPEC = createGapRowSpec(LayoutStyle
245: .getCurrent().getRelatedComponentsPadY());
246:
247: /**
248: * Describes a logical vertical gap between two unrelated components.<p>
249: *
250: * <strong>Note:</strong> In a future version this constant will likely
251: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
252: *
253: * @see #RELATED_GAP_ROWSPEC
254: */
255: public static final RowSpec UNRELATED_GAP_ROWSPEC = createGapRowSpec(LayoutStyle
256: .getCurrent().getUnrelatedComponentsPadY());
257:
258: /**
259: * Describes a logical vertical narrow gap between two rows in the grid.
260: * Useful if the vertical space is scarce or if an individual vertical gap
261: * shall be small than the default line gap.<p>
262: *
263: * <strong>Note:</strong> In a future version this constant will likely
264: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
265: *
266: * @see #LINE_GAP_ROWSPEC
267: * @see #PARAGRAPH_GAP_ROWSPEC
268: */
269: public static final RowSpec NARROW_LINE_GAP_ROWSPEC = createGapRowSpec(LayoutStyle
270: .getCurrent().getNarrowLinePad());
271:
272: /**
273: * Describes the logical vertical default gap between two rows in the grid.
274: * A little bit larger than the narrow line gap.<p>
275: *
276: * <strong>Note:</strong> In a future version this constant will likely
277: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
278: *
279: * @see #NARROW_LINE_GAP_ROWSPEC
280: * @see #PARAGRAPH_GAP_ROWSPEC
281: */
282: public static final RowSpec LINE_GAP_ROWSPEC = createGapRowSpec(LayoutStyle
283: .getCurrent().getLinePad());
284:
285: /**
286: * Describes the logical vertical default gap between two paragraphs in
287: * the layout grid. This gap is larger than the default line gap.<p>
288: *
289: * <strong>Note:</strong> In a future version this constant will likely
290: * be moved to a class <code>LogicalSize</code> or <code>StyledSize</code>.
291: *
292: * @see #NARROW_LINE_GAP_ROWSPEC
293: * @see #LINE_GAP_ROWSPEC
294: */
295: public static final RowSpec PARAGRAPH_GAP_ROWSPEC = createGapRowSpec(LayoutStyle
296: .getCurrent().getParagraphPad());
297:
298: // Factory Methods ******************************************************
299:
300: /**
301: * Creates and returns an instance of <code>FormLayout</code>
302: * to build forms with the specified number of major and minor columns.<p>
303: *
304: * The layout will use default values for all gaps.<p>
305: *
306: * <strong>This method will be removed from version 1.2.</strong>
307: *
308: * @param majorColumns the number of used major columns
309: * @param minorColumns the number of used minor columns
310: * @param labelColumnSpec specifies the label columns
311: * @return a prepared <code>FormLayout</code>
312: *
313: * @deprecated This method will be removed from the Forms 1.2
314: */
315: public static FormLayout createColumnLayout(int majorColumns,
316: int minorColumns, ColumnSpec labelColumnSpec) {
317: return createColumnLayout(majorColumns, minorColumns,
318: labelColumnSpec, Sizes.DLUX14, Sizes.DLUX2);
319: }
320:
321: /**
322: * Creates and returns an instance of <code>FormLayout</code>
323: * to build forms with the given number of major columns.
324: * Major columns consists of a label and a component section, where each
325: * component section is divided into the given number of minor columns.<p>
326: *
327: * The layout will use the specified gaps to separate major columns,
328: * and the label and component section.<p>
329: *
330: * <strong>This method will be removed from version 1.2.</strong>
331: *
332: * @param majorColumns the number of major columns
333: * @param minorColumns the number of minor columns
334: * @param labelColumnSpec specifies the label columns
335: * @param indent an optional <code>ConstantSize</code>
336: * that describes the width of the leading indent column
337: * @param minorColumnGap a <code>ConstantSize</code> that describes
338: * the gap between minor columns
339: * @return a prepared <code>FormLayout</code>
340: *
341: * @deprecated This method will be removed from the Forms 1.2
342: */
343: public static FormLayout createColumnLayout(int majorColumns,
344: int minorColumns, ColumnSpec labelColumnSpec,
345: ConstantSize indent, ConstantSize minorColumnGap) {
346: return createColumnLayout(majorColumns, minorColumns,
347: labelColumnSpec, PREF_COLSPEC, indent, Sizes.DLUX14,
348: minorColumnGap);
349: }
350:
351: /**
352: * Creates and returns an instance of <code>FormLayout</code>
353: * to build forms with the given number of major columns.
354: * Major columns consists of a label and a component section, where each
355: * component section is divided into the given number of minor columns.<p>
356: *
357: * The layout will use the specified gaps to separate major columns,
358: * minor columns, and the label and component section.<p>
359: *
360: * <strong>This method will be removed from version 1.2.</strong>
361: *
362: * @param majorColumns the number of major columns
363: * @param minorColumns the number of minor columns
364: * @param labelColumnSpec specifies the label columns
365: * @param componentColumnSpec specifies the label columns
366: * @param indent an optional <code>ConstantSize</code>
367: * that describes the width of the leading indent column
368: * @param majorColumnGap a <code>ConstantSize</code> that describes
369: * the gap between major columns
370: * @param minorColumnGap a <code>ConstantSize</code> that describes
371: * the gap between minor columns
372: * @return a prepared <code>FormLayout</code>
373: *
374: * @deprecated This method will be removed from the Forms 1.2
375: */
376: public static FormLayout createColumnLayout(int majorColumns,
377: int minorColumns, ColumnSpec labelColumnSpec,
378: ColumnSpec componentColumnSpec, ConstantSize indent,
379: ConstantSize majorColumnGap, ConstantSize minorColumnGap) {
380:
381: ColumnSpec majorGapColSpec = createGapColumnSpec(majorColumnGap);
382: ColumnSpec minorGapColSpec = createGapColumnSpec(minorColumnGap);
383: FormLayout layout = new FormLayout(new ColumnSpec[] {},
384: new RowSpec[] {});
385:
386: // Add the optional leading indent.
387: if (indent != null) {
388: layout.appendColumn(createGapColumnSpec(indent));
389: }
390: for (int i = 0; i < majorColumns; i++) {
391: // Add the optional label column with gap.
392: if (labelColumnSpec != null) {
393: layout.appendColumn(labelColumnSpec);
394: layout.appendColumn(RELATED_GAP_COLSPEC);
395: }
396: // Add the minor columns with separating gaps.
397: for (int j = 0; j < minorColumns; j++) {
398: layout.appendColumn(componentColumnSpec);
399: layout.addGroupedColumn(layout.getColumnCount());
400: if (j < minorColumns - 1) {
401: layout.appendColumn(minorGapColSpec);
402: }
403: }
404: // Add a gap between major columns.
405: if (i < majorColumns - 1) {
406: layout.appendColumn(majorGapColSpec);
407: }
408: }
409: return layout;
410: }
411:
412: // Helper Code **********************************************************
413:
414: /**
415: * Creates and returns a {@link ColumnSpec} that represents a gap with the
416: * specified {@link ConstantSize}.
417: *
418: * @param gapSize a <code>ConstantSize</code> that specifies the gap
419: * @return a <code>ColumnSpec</code> that describes a horizontal gap
420: */
421: public static ColumnSpec createGapColumnSpec(ConstantSize gapSize) {
422: return new ColumnSpec(ColumnSpec.LEFT, gapSize,
423: ColumnSpec.NO_GROW);
424: }
425:
426: /**
427: * Creates and returns a {@link RowSpec} that represents a gap with the
428: * specified {@link ConstantSize}.
429: *
430: * @param gapSize a <code>ConstantSize</code> that specifies the gap
431: * @return a <code>RowSpec</code> that describes a vertical gap
432: */
433: public static RowSpec createGapRowSpec(ConstantSize gapSize) {
434: return new RowSpec(RowSpec.TOP, gapSize, RowSpec.NO_GROW);
435: }
436:
437: }
|