001    /*
002     * Copyright 2002-2004 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.form.builder;
017    
018    import javax.swing.JComponent;
019    import javax.swing.JLabel;
020    import javax.swing.JPanel;
021    
022    import org.springframework.richclient.factory.ComponentFactory;
023    import org.springframework.richclient.form.FormModelHelper;
024    import org.springframework.richclient.form.binding.BindingFactory;
025    import org.springframework.richclient.layout.GridBagLayoutBuilder;
026    import org.springframework.richclient.layout.LabelOrientation;
027    import org.springframework.richclient.layout.LayoutBuilder;
028    
029    /**
030     * @see GridBagLayoutBuilder
031     */
032    public class GridBagLayoutFormBuilder extends AbstractFormBuilder implements LayoutBuilder {
033    
034        private final GridBagLayoutBuilder builder;
035    
036        public GridBagLayoutFormBuilder(BindingFactory bindingFactory) {
037            super(bindingFactory);
038            this.builder = new FormModelAwareGridBagLayoutBuilder();
039        }
040    
041        /**
042         * Returns the underlying {@link GridBagLayoutBuilder}. Should be used with
043         * caution.
044         *
045         * @return never null
046         */
047        public final GridBagLayoutBuilder getBuilder() {
048            return builder;
049        }
050    
051        public void setComponentFactory(ComponentFactory componentFactory) {
052            super.setComponentFactory(componentFactory);
053            builder.setComponentFactory(componentFactory);
054        }
055    
056        /**
057         * Appends a label and field to the end of the current line.
058         * <p />
059         *
060         * The label will be to the left of the field, and be right-justified.
061         * <br />
062         * The field will "grow" horizontally as space allows.
063         * <p />
064         *
065         * @param propertyName the name of the property to create the controls for
066         *
067         * @return "this" to make it easier to string together append calls
068         *
069         * @see FormModelHelper#createLabel(String)
070         * @see FormModelHelper#createBoundControl(String)
071         */
072        public GridBagLayoutFormBuilder appendLabeledField(String propertyName) {
073            return appendLabeledField(propertyName, LabelOrientation.LEFT);
074        }
075    
076        /**
077         * Appends a label and field to the end of the current line.
078         * <p />
079         *
080         * The label will be to the left of the field, and be right-justified.
081         * <br />
082         * The field will "grow" horizontally as space allows.
083         * <p />
084         *
085         * @param propertyName the name of the property to create the controls for
086         * @param colSpan      the number of columns the field should span
087         *
088         * @return "this" to make it easier to string together append calls
089         *
090         * @see FormModelHelper#createLabel(String)
091         * @see FormModelHelper#createBoundControl(String)
092         */
093        public GridBagLayoutFormBuilder appendLabeledField(String propertyName, int colSpan) {
094            return appendLabeledField(propertyName, LabelOrientation.LEFT, colSpan);
095        }
096    
097        /**
098         * Appends a label and field to the end of the current line.
099         * <p />
100         *
101         * The label will be to the left of the field, and be right-justified.
102         * <br />
103         * The field will "grow" horizontally as space allows.
104         * <p />
105         *
106         * @param propertyName the name of the property to create the controls for
107         *
108         * @return "this" to make it easier to string together append calls
109         *
110         * @see FormModelHelper#createLabel(String)
111         * @see FormModelHelper#createBoundControl(String)
112         */
113        public GridBagLayoutFormBuilder appendLabeledField(String propertyName, LabelOrientation labelOrientation) {
114            return appendLabeledField(propertyName, labelOrientation, 1);
115        }
116    
117        /**
118         * Appends a label and field to the end of the current line.
119         * <p />
120         *
121         * The label will be to the left of the field, and be right-justified.
122         * <br />
123         * The field will "grow" horizontally as space allows.
124         * <p />
125         *
126         * @param propertyName the name of the property to create the controls for
127         * @param colSpan      the number of columns the field should span
128         *
129         * @return "this" to make it easier to string together append calls
130         *
131         * @see FormModelHelper#createLabel(String)
132         * @see FormModelHelper#createBoundControl(String)
133         */
134        public GridBagLayoutFormBuilder appendLabeledField(String propertyName, LabelOrientation labelOrientation,
135                int colSpan) {
136            final JComponent field = createDefaultBinding(propertyName).getControl();
137    
138            return appendLabeledField(propertyName, field, labelOrientation, colSpan);
139        }
140    
141        /**
142         * Appends a label and field to the end of the current line.
143         * <p />
144         *
145         * The label will be to the left of the field, and be right-justified.
146         * <br />
147         * The field will "grow" horizontally as space allows.
148         * <p />
149         *
150         * @param propertyName the name of the property to create the controls for
151         *
152         * @return "this" to make it easier to string together append calls
153         *
154         * @see FormModelHelper#createLabel(String)
155         * @see FormModelHelper#createBoundControl(String)
156         */
157        public GridBagLayoutFormBuilder appendLabeledField(String propertyName, final JComponent field,
158                LabelOrientation labelOrientation) {
159            return appendLabeledField(propertyName, field, labelOrientation, 1);
160        }
161    
162        /**
163         * Appends a label and field to the end of the current line.
164         * <p />
165         *
166         * The label will be to the left of the field, and be right-justified.
167         * <br />
168         * The field will "grow" horizontally as space allows.
169         * <p />
170         *
171         * @param propertyName the name of the property to create the controls for
172         * @param colSpan      the number of columns the field should span
173         *
174         * @return "this" to make it easier to string together append calls
175         *
176         * @see FormModelHelper#createLabel(String)
177         * @see FormComponentInterceptor#processLabel(String, JComponent)
178         */
179        public GridBagLayoutFormBuilder appendLabeledField(String propertyName, final JComponent field,
180                LabelOrientation labelOrientation, int colSpan) {
181            return appendLabeledField(propertyName, field, labelOrientation, colSpan, 1, true, false);
182        }
183    
184        /**
185         * Appends a label and field to the end of the current line.
186         * <p />
187         *
188         * The label will be to the left of the field, and be right-justified.
189         * <br />
190         * The field will "grow" horizontally as space allows.
191         * <p />
192         *
193         * @param propertyName the name of the property to create the controls for
194         * @param colSpan      the number of columns the field should span
195         *
196         * @return "this" to make it easier to string together append calls
197         *
198         * @see FormModelHelper#createLabel(String)
199         * @see FormComponentInterceptor#processLabel(String, JComponent)
200         */
201        public GridBagLayoutFormBuilder appendLabeledField(String propertyName, final JComponent field,
202                LabelOrientation labelOrientation, int colSpan, int rowSpan, boolean expandX, boolean expandY) {
203            builder.appendLabeledField(propertyName, field, labelOrientation, colSpan, rowSpan, expandX, expandY);
204            return this;
205        }
206    
207        /**
208         * Appends a separator (usually a horizontal line). Has an implicit
209         * {@link #nextLine()}before and after it.
210         *
211         * @return "this" to make it easier to string together append calls
212         */
213        public GridBagLayoutFormBuilder appendSeparator() {
214            return appendSeparator(null);
215        }
216    
217        /**
218         * Appends a separator (usually a horizontal line) using the provided string
219         * as the key to look in the
220         * {@link #setComponentFactory(ComponentFactory) ComponentFactory's}message
221         * bundle for the text to put along with the separator. Has an implicit
222         * {@link #nextLine()}before and after it.
223         *
224         * @return "this" to make it easier to string together append calls
225         */
226        public GridBagLayoutFormBuilder appendSeparator(String labelKey) {
227            builder.appendSeparator(labelKey);
228            return this;
229        }
230    
231        /**
232         * Ends the current line and starts a new one
233         *
234         * @return "this" to make it easier to string together append calls
235         */
236        public GridBagLayoutFormBuilder nextLine() {
237            builder.nextLine();
238            return this;
239        }
240    
241        /**
242         * Should this show "guidelines"? Useful for debugging layouts.
243         */
244        public void setShowGuidelines(boolean showGuidelines) {
245            builder.setShowGuidelines(showGuidelines);
246        }
247    
248        /**
249         * Creates and returns a JPanel with all the given components in it, using
250         * the "hints" that were provided to the builder.
251         *
252         * @return a new JPanel with the components laid-out in it
253         */
254        public JPanel getPanel() {
255            return builder.getPanel();
256        }
257    
258        /**
259         * @see GridBagLayoutBuilder#setAutoSpanLastComponent(boolean)
260         */
261        public void setAutoSpanLastComponent(boolean autoSpanLastComponent) {
262            builder.setAutoSpanLastComponent(autoSpanLastComponent);
263        }
264    
265        protected final class FormModelAwareGridBagLayoutBuilder extends GridBagLayoutBuilder {
266            protected JLabel createLabel(String propertyName) {
267                JLabel label = getComponentFactory().createLabel("");
268                getFormModel().getFieldFace(propertyName).configure(label);
269                return label;
270            }
271        }
272    }