001 /*
002 * Copyright 2002-2007 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 java.util.HashMap;
019 import java.util.Map;
020
021 import javax.swing.JComboBox;
022 import javax.swing.JComponent;
023 import javax.swing.JLabel;
024 import javax.swing.JPasswordField;
025
026 import org.springframework.binding.form.FormModel;
027 import org.springframework.rules.constraint.Constraint;
028 import org.springframework.richclient.application.ApplicationServicesLocator;
029 import org.springframework.richclient.factory.ComponentFactory;
030 import org.springframework.richclient.form.binding.Binding;
031 import org.springframework.richclient.form.binding.BindingFactory;
032 import org.springframework.richclient.form.binding.swing.ComboBoxBinder;
033 import org.springframework.util.Assert;
034
035 /**
036 * Base class for form builders.
037 *
038 * @author oliverh
039 * @author Mathias Broekelmann
040 */
041 public abstract class AbstractFormBuilder {
042
043 private final BindingFactory bindingFactory;
044
045 private ComponentFactory componentFactory;
046
047 private FormComponentInterceptor interceptor;
048
049 private FormComponentInterceptorFactory interceptorFactory;
050
051 /**
052 * Default constructor providing the {@link BindingFactory}.
053 *
054 * @param bindingFactory the factory creating the {@link Binding}s.
055 */
056 protected AbstractFormBuilder(BindingFactory bindingFactory) {
057 Assert.notNull(bindingFactory);
058 this.bindingFactory = bindingFactory;
059 }
060
061 /**
062 * Returns the {@link FormComponentInterceptor} that will be used when
063 * creating a component with this builder.
064 */
065 protected FormComponentInterceptor getFormComponentInterceptor() {
066 if (interceptor == null) {
067 if (interceptorFactory == null) {
068 interceptorFactory = (FormComponentInterceptorFactory) ApplicationServicesLocator.services()
069 .getService(FormComponentInterceptorFactory.class);
070 }
071 interceptor = interceptorFactory.getInterceptor(getFormModel());
072 }
073
074 return interceptor;
075 }
076
077 /**
078 * Set the factory that delivers the {@link FormComponentInterceptor}.
079 */
080 public void setFormComponentInterceptorFactory(FormComponentInterceptorFactory interceptorFactory) {
081 this.interceptorFactory = interceptorFactory;
082 this.interceptor = null;
083 }
084
085 /**
086 * Returns the {@link ComponentFactory} that delivers all the visual
087 * components.
088 */
089 protected ComponentFactory getComponentFactory() {
090 if (componentFactory == null) {
091 componentFactory = (ComponentFactory) ApplicationServicesLocator.services().getService(
092 ComponentFactory.class);
093 }
094 return componentFactory;
095 }
096
097 /**
098 * Set the {@link ComponentFactory}.
099 */
100 public void setComponentFactory(ComponentFactory componentFactory) {
101 this.componentFactory = componentFactory;
102 }
103
104 /**
105 * Returns the {@link BindingFactory}.
106 */
107 protected BindingFactory getBindingFactory() {
108 return bindingFactory;
109 }
110
111 /**
112 * Convenience method to return the formModel that is used in the
113 * {@link BindingFactory} and that should be used in the builder.
114 */
115 protected FormModel getFormModel() {
116 return bindingFactory.getFormModel();
117 }
118
119 /**
120 * Create a binding by looking up the appropriate registered binding.
121 *
122 * @param fieldName the name of the property to bind.
123 * @return the {@link Binding} for the property which provides a component
124 * that is bound to the valueModel of the property.
125 */
126 protected Binding createDefaultBinding(String fieldName) {
127 return getBindingFactory().createBinding(fieldName);
128 }
129
130 /**
131 * Create a binding that uses the given component instead of its default
132 * component.
133 *
134 * @param fieldName the name of the property to bind.
135 * @param component the component to bind to the property.
136 * @return the {@link Binding} that binds the component to the valuemodel of
137 * the property.
138 */
139 protected Binding createBinding(String fieldName, JComponent component) {
140 return getBindingFactory().bindControl(component, fieldName);
141 }
142
143 /**
144 * Create a binding that uses the given component instead of its default
145 * component. Additionally providing a context which is used by the binding
146 * to allow custom settings.
147 *
148 * @param fieldName the name of the property to bind.
149 * @param component the component to bind to the property.
150 * @param context a map of with additional settings providing a specific
151 * context.
152 * @return the {@link Binding} that binds the component to the valuemodel of
153 * the property.
154 */
155 protected Binding createBinding(String fieldName, JComponent component, Map context) {
156 return getBindingFactory().bindControl(component, fieldName, context);
157 }
158
159 /**
160 * Creates a component which is used as a selector in the form. This
161 * implementation creates a {@link JComboBox}
162 *
163 * @param fieldName the name of the field for the selector
164 * @param filter an optional filter constraint
165 * @return the component to use for a selector, not null
166 */
167 protected JComponent createSelector(String fieldName, Constraint filter) {
168 Map context = new HashMap();
169 context.put(ComboBoxBinder.FILTER_KEY, filter);
170 return getBindingFactory().createBinding(JComboBox.class, fieldName).getControl();
171 }
172
173 /**
174 * Creates a component which is used as a scrollpane for a component
175 *
176 * @param fieldName the fieldname for the scrollpane
177 * @param component the component to place into the scrollpane
178 * @return the scrollpane component
179 */
180 protected JComponent createScrollPane(String fieldName, JComponent component) {
181 return getComponentFactory().createScrollPane(component);
182 }
183
184 /**
185 * Create a password field for the given property.
186 *
187 * @param fieldName the name of the property.
188 * @return the password field.
189 */
190 protected JPasswordField createPasswordField(String fieldName) {
191 return getComponentFactory().createPasswordField();
192 }
193
194 /**
195 * Create a textarea for the given property.
196 *
197 * @param fieldName the name of the property.
198 * @return the textarea.
199 */
200 protected JComponent createTextArea(String fieldName) {
201 return getComponentFactory().createTextArea(5, 40);
202 }
203
204 /**
205 * Create a label for the property.
206 *
207 * @param fieldName the name of the property.
208 * @param component the component of the property which is related to the
209 * label.
210 * @return a {@link JLabel} for the property.
211 */
212 protected JLabel createLabelFor(String fieldName, JComponent component) {
213 JLabel label = getComponentFactory().createLabel("");
214 getFormModel().getFieldFace(fieldName).configure(label);
215 label.setLabelFor(component);
216
217 FormComponentInterceptor interceptor = getFormComponentInterceptor();
218 if (interceptor != null) {
219 interceptor.processLabel(fieldName, label);
220 }
221
222 return label;
223 }
224 }