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.tutorial.building;
032:
033: import java.awt.Component;
034: import java.awt.Insets;
035:
036: import javax.swing.JComponent;
037: import javax.swing.JFrame;
038: import javax.swing.JTextField;
039: import javax.swing.UIManager;
040: import javax.swing.WindowConstants;
041:
042: import com.jgoodies.forms.builder.DefaultFormBuilder;
043: import com.jgoodies.forms.builder.PanelBuilder;
044: import com.jgoodies.forms.layout.CellConstraints;
045: import com.jgoodies.forms.layout.ColumnSpec;
046: import com.jgoodies.forms.layout.FormLayout;
047: import com.jgoodies.forms.layout.RowSpec;
048: import com.jgoodies.forms.layout.FormSpec.DefaultAlignment;
049:
050: /**
051: * Demonstrates how to build panels that honor or ignore the current
052: * component orientation: left-to-right vs. right-to-left.<p>
053: *
054: * This example uses a utility class that may be moved to the extras or
055: * to the Forms core in a future version. The tricky part is the abstract
056: * definition of column specifications and cell constraints.<p>
057: *
058: * The example below utilizes the <code>OrientationUtils</code> to flip
059: * column specification defaul alignments and to reverse the order of
060: * column specifications. Cell constraints need to be adjusted too; this
061: * example avoids the problem by using a builder that creates <em>all</em>
062: * cell constraints.<p>
063: *
064: * You can find information about the latest additions regarding the
065: * Forms support for different component orientations in the comments for
066: * <a href="http://forms.dev.java.net/issues/show_bug.cgi?id=2">issue #2</a>.
067: *
068: * @author Karsten Lentzsch
069: * @version $Revision: 1.11 $
070: *
071: * @see com.jgoodies.forms.builder.AbstractFormBuilder
072: * @see com.jgoodies.forms.builder.DefaultFormBuilder
073: */
074: public final class ComponentOrientationExample {
075:
076: public static void main(String[] args) {
077: try {
078: UIManager
079: .setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
080: } catch (Exception e) {
081: // Likely PlasticXP is not in the class path; ignore.
082: }
083: JFrame frame = new JFrame();
084: frame.setTitle("Forms Tutorial :: Component Orientation");
085: frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
086: JComponent panel = new ComponentOrientationExample()
087: .buildPanel();
088: frame.getContentPane().add(panel);
089: frame.pack();
090: frame.setVisible(true);
091: }
092:
093: public JComponent buildPanel() {
094: FormLayout layout = new FormLayout("pref:grow");
095: DefaultFormBuilder rowBuilder = new DefaultFormBuilder(layout);
096: rowBuilder.setDefaultDialogBorder();
097:
098: rowBuilder.append(buildSample("Left to Right", true));
099: rowBuilder.append(buildSample("Right to Left", false));
100: rowBuilder.append(buildSample("Default Orientation",
101: new PanelBuilder(layout).isLeftToRight()));
102:
103: return rowBuilder.getPanel();
104: }
105:
106: /**
107: * Creates and returns a sample panel that consists of a titled
108: * separator and two component lines each with a 'leading' label.
109: * Honors the specified component orientation.<p>
110: *
111: * The builder code avoids creating individual cell constraints;
112: * all cell constraints used in the example below will be created
113: * on-the-fly by the builder layer.<p>
114: *
115: * Note that cell constraints should be flipped and repositioned
116: * if they are intended for being used with left-to-right and
117: * right-to-left layouts.
118: *
119: * @return the sample panel
120: */
121: private Component buildSample(String title, boolean leftToRight) {
122: String leftToRightSpecs = "right:pref, 4dlu, pref:grow, 3dlu, pref:grow";
123: FormLayout layout = leftToRight ? new FormLayout(
124: leftToRightSpecs) : new FormLayout(OrientationUtils
125: .flipped(leftToRightSpecs), new RowSpec[] {});
126: DefaultFormBuilder builder = new DefaultFormBuilder(layout);
127: builder.setLeftToRight(leftToRight);
128: builder.setDefaultDialogBorder();
129:
130: builder.appendSeparator(title);
131: builder.append("Level");
132: builder.append(new JTextField(10), 3);
133:
134: builder.append("Radar", new JTextField(10));
135: builder.append(new JTextField(10));
136: return builder.getPanel();
137: }
138:
139: // Helper Code ************************************************************
140:
141: /**
142: * Provides some convenience behavior for flipping side in column
143: * specifications, arrays of column specifications and encoded
144: * column specs.
145: */
146: private static final class OrientationUtils {
147:
148: private OrientationUtils() {
149: // Overrides default constructor; prevents instantiation.
150: }
151:
152: /**
153: * Flips the default alignment of the given column specification
154: * and returns a new column specification object with the flipped
155: * alignment and the same size and growing behavior as the original.
156: *
157: * @param spec the original column specification
158: * @return the column specification with flipped default alignment
159: */
160: static ColumnSpec flipped(ColumnSpec spec) {
161: DefaultAlignment alignment = spec.getDefaultAlignment();
162: if (alignment == ColumnSpec.LEFT)
163: alignment = ColumnSpec.RIGHT;
164: else if (alignment == ColumnSpec.RIGHT)
165: alignment = ColumnSpec.LEFT;
166: return new ColumnSpec(alignment, spec.getSize(), spec
167: .getResizeWeight());
168: }
169:
170: /**
171: * Returns an array of column specifications that is built from the
172: * given array by flipping each column spec and reversing their order.
173: *
174: * @param original the original array of column specifications
175: * @return an array of flipped column specs in reversed order
176: */
177: static ColumnSpec[] flipped(ColumnSpec[] original) {
178: int length = original.length;
179: ColumnSpec[] flipped = new ColumnSpec[length];
180: for (int i = 0; i < length; i++) {
181: flipped[i] = flipped(original[length - 1 - i]);
182: }
183: return flipped;
184: }
185:
186: /**
187: * Returns an array of column specifications that is built from the
188: * given encoded column specifications by flipping each column spec
189: * and reversing their order.
190: *
191: * @param encodedColumnSpecs the original comma-separated encoded
192: * column specifications
193: * @return an array of flipped column specs in reversed order
194: */
195: static ColumnSpec[] flipped(String encodedColumnSpecs) {
196: return flipped(ColumnSpec.decodeSpecs(encodedColumnSpecs));
197: }
198:
199: /**
200: * Creates and returns a horizontally flipped clone of the
201: * given cell constraints object. Flips the horizontal alignment
202: * and the left and right insets.
203: *
204: * @param cc the original cell constraints object
205: * @return the flipped cell constraints with flipped horizontal
206: * alignment, and flipped left and right insets - if any
207: */
208: static CellConstraints flipHorizontally(CellConstraints cc) {
209: CellConstraints.Alignment flippedHAlign = cc.hAlign;
210: if (flippedHAlign == CellConstraints.LEFT)
211: flippedHAlign = CellConstraints.RIGHT;
212: else if (flippedHAlign == CellConstraints.RIGHT)
213: flippedHAlign = CellConstraints.LEFT;
214:
215: CellConstraints flipped = new CellConstraints(cc.gridX,
216: cc.gridY, cc.gridWidth, cc.gridHeight,
217: flippedHAlign, cc.vAlign);
218: if (cc.insets != null) {
219: flipped.insets = new Insets(cc.insets.top,
220: cc.insets.right, cc.insets.bottom,
221: cc.insets.left);
222: }
223: return flipped;
224: }
225:
226: /**
227: * Creates and returns a horizontally flipped clone of the
228: * given cell constraints object with the grid position adjusted
229: * to the given column count. Flips the horizontal alignment
230: * and the left and right insets. And swaps the left and right
231: * cell positions according to the specified column count.
232: *
233: * @param cc the original cell constraints object
234: * @param columnCount the number of columns;
235: * used to swap the left and right cell bounds
236: * @return the flipped cell constraints with flipped horizontal
237: * alignment, and flipped left and right insets - if any
238: */
239: static CellConstraints flipHorizontally(CellConstraints cc,
240: int columnCount) {
241: CellConstraints flipped = flipHorizontally(cc);
242: flipped.gridX = columnCount + 1 - cc.gridX;
243: return flipped;
244: }
245: }
246:
247: }
|