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 }