1 7 8 package org.jdesktop.swing.binding; 9 10 import org.jdesktop.swing.data.ConversionException; 11 import org.jdesktop.swing.data.Converter; 12 import org.jdesktop.swing.data.DataModel; 13 import org.jdesktop.swing.data.MetaData; 14 import org.jdesktop.swing.data.Validator; 15 import org.jdesktop.swing.data.ValueChangeEvent; 16 import org.jdesktop.swing.data.ValueChangeListener; 17 import java.beans.PropertyChangeListener ; 18 import java.beans.PropertyChangeSupport ; 19 20 import java.util.ArrayList ; 21 22 import javax.swing.InputVerifier ; 23 import javax.swing.JComponent ; 24 25 34 35 public abstract class AbstractBinding implements Binding { 36 37 protected DataModel dataModel; 38 protected MetaData metaData; 39 private String fieldName; 40 protected Object cachedValue; 41 protected ArrayList errorList; 42 protected boolean modified = false; 43 protected int validState = UNVALIDATED; 44 protected boolean pulling = false; 45 protected boolean pushing = false; 46 47 private PropertyChangeSupport pcs; 48 private int validationPolicy; 49 private static final PropertyChangeListener [] 50 EMPTY_PROPERTY_CHANGE_LISTENER_ARRAY = new PropertyChangeListener [0]; 51 52 61 protected AbstractBinding(JComponent component, 62 DataModel dataModel, String fieldName, 63 int validationPolicy) { 64 checkNull(component, "component must not be null"); 65 checkNull(dataModel, "model must not be null"); 66 checkNull(fieldName, "fieldName must not be null"); 67 installDataModel(dataModel, fieldName); 68 setComponent(component); 69 setValidationPolicy(validationPolicy); 70 } 71 72 74 public DataModel getDataModel() { 75 return dataModel; 76 } 77 78 public String getFieldName() { 79 return fieldName; 80 } 81 82 86 public void setValidationPolicy(int policy) { 87 int oldValidationPolicy = this.validationPolicy; 88 this.validationPolicy = policy; 89 installInputVerifier(); 90 if (policy != oldValidationPolicy) { 91 firePropertyChange("validationPolicy", 92 new Integer (oldValidationPolicy), 93 new Integer (policy)); 94 } 95 } 96 97 98 public int getValidationPolicy() { 99 return validationPolicy; 100 } 101 102 public boolean pull() { 103 pulling = true; 104 cachedValue = dataModel.getValue(metaData.getName()); 106 setComponentValue(cachedValue); 107 setModified(false); 109 setValidState(UNVALIDATED); 110 isValid(); 112 pulling = false; 113 return true; 114 } 115 116 public boolean push() { 117 if (isValid()) { 118 pushing = true; 119 dataModel.setValue(metaData.getName(), cachedValue); 120 setModified(false); 121 pushing = false; 122 return true; 123 } 124 return false; 125 } 126 127 public boolean isModified() { 128 return modified; 129 } 130 131 public boolean isValid() { 132 if (validState != UNVALIDATED) { 133 return validState == VALID; 134 } 135 clearValidationErrors(); 137 Object componentValue = getComponentValue(); 138 139 boolean ok = checkRequired(componentValue); 141 142 Object convertedValue = null; 145 if (ok) { 146 try { 147 convertedValue = convertToModelType(componentValue); 148 } catch (Exception e) { 149 ok = false; 150 151 addError("value must be type " + metaData.getElementClass().getName()); 152 } 153 } 154 155 if (ok) { 157 ok = executeValidators(convertedValue); 158 } 159 160 if (ok) { 161 cachedValue = convertedValue; 162 } 163 setValidState(ok? VALID : INVALID); 164 165 return validState == VALID; 166 167 } 168 169 public int getValidState() { 170 return validState; 171 } 172 173 174 public String [] getValidationErrors() { 175 if (errorList != null) { 176 return (String [])errorList.toArray(new String [1]); 177 } 178 return new String [0]; 179 } 180 181 public void clearValidationErrors() { 182 if (errorList != null) { 183 errorList.clear(); 184 } 185 } 186 187 188 193 public void addPropertyChangeListener(PropertyChangeListener pcl) { 194 if (pcs == null) { 195 pcs = new PropertyChangeSupport (this); 196 197 } 198 pcs.addPropertyChangeListener(pcl); 199 } 200 201 206 public void removePropertyChangeListener(PropertyChangeListener pcl) { 207 pcs.removePropertyChangeListener(pcl); 208 } 209 210 215 public PropertyChangeListener [] getPropertyChangeListeners() { 216 if (pcs == null) return EMPTY_PROPERTY_CHANGE_LISTENER_ARRAY; 217 return pcs.getPropertyChangeListeners(); 218 } 219 220 protected void firePropertyChange(String propertyName, 221 Object oldValue, Object newValue) { 222 if (pcs == null) return; 223 pcs.firePropertyChange(propertyName, oldValue, newValue); 224 } 225 226 227 229 233 protected abstract void setComponent(JComponent component); 234 protected abstract Object getComponentValue(); 235 protected abstract void setComponentValue(Object value); 236 237 239 protected boolean checkRequired(Object componentValue) { 240 if (metaData.isRequired() && isEmpty(componentValue)) { 242 addError("requires a value"); 243 return false; 244 } 245 return true; 246 } 249 250 protected boolean isEmpty(Object componentValue) { 251 return (componentValue == null || 252 (componentValue instanceof String && ((String )componentValue).equals(""))); 253 } 254 255 protected Object convertToModelType(Object componentValue) throws ConversionException { 256 Object convertedValue = null; 257 if (isEmpty(componentValue)) { 260 return convertedValue; 261 } 262 Class elementClass = metaData.getElementClass(); 263 if (componentValue instanceof String ) { 264 String stringValue = (String ) componentValue; 265 Converter converter = metaData.getConverter(); 266 if (converter != null) { 267 convertedValue = converter.decode(stringValue, 268 metaData.getDecodeFormat()); 269 } else if (metaData.getElementClass() == String .class) { 270 convertedValue = componentValue; 271 } 272 } 273 else { 274 if (!elementClass.isAssignableFrom(componentValue.getClass())) { 275 throw new ConversionException("cannot assign component value"); 276 } else { 277 convertedValue = componentValue; 278 } 279 } 280 return convertedValue; 281 } 282 283 protected String convertFromModelType(Object modelValue) { 284 if (modelValue != null) { 285 try { 286 Converter converter = metaData.getConverter(); 287 return converter.encode(modelValue, metaData.getEncodeFormat()); 288 } 289 catch (Exception e) { 290 291 return modelValue.toString(); 292 } 293 } 294 return ""; 295 } 296 297 protected boolean executeValidators(Object value) { 298 Validator validators[] = metaData.getValidators(); 299 boolean isValid = true; 300 for (int i = 0; i < validators.length; i++) { 301 String error[] = new String [1]; 302 boolean passed = validators[i].validate(value, null, error); 303 if (!passed) { 304 String errorMessage = error[0]; 305 if (errorMessage != null) { 306 addError(errorMessage); 307 } 308 isValid = false; 309 } 310 } 311 return isValid; 312 } 313 314 protected void addError(String error) { 315 if (errorList == null) { 316 errorList = new ArrayList (); 317 } 318 errorList.add(error); 319 } 320 321 322 protected void setModified(boolean modified) { 323 boolean oldModified = this.modified; 328 this.modified = modified; 329 if (modified) { 330 cachedValue = null; 331 setValidState(UNVALIDATED); 332 } 333 if (oldModified != modified) { 334 firePropertyChange("modified", 335 Boolean.valueOf(oldModified), 336 Boolean.valueOf(modified)); 337 } 338 } 339 340 protected void setValidState(int validState) { 341 int oldValidState = this.validState; 342 this.validState = validState; 343 if (oldValidState != validState && 344 validState == UNVALIDATED) { 345 clearValidationErrors(); 346 } 347 if (validState != oldValidState) { 348 firePropertyChange("validState", 349 new Integer (oldValidState), 350 new Integer (validState)); 351 } 352 } 353 354 355 358 protected void installInputVerifier() { 359 getComponent().setInputVerifier(new InputVerifier () { 360 public boolean verify(JComponent input) { 361 if (validationPolicy != AUTO_VALIDATE_NONE) { 362 boolean isValid = isValid(); 363 if (!isValid && validationPolicy == AUTO_VALIDATE_STRICT) { 364 return false; 365 } 366 return true; 367 } 368 return true; 369 } 370 }); 371 } 372 373 375 protected void checkNull(Object component, String message) { 376 if (component == null) throw new NullPointerException (message); 377 } 378 379 protected void installDataModel(DataModel dataModel, String fieldName) { 380 this.dataModel = dataModel; 381 this.fieldName = fieldName; 382 metaData = dataModel.getMetaData(fieldName); 383 installDataModelListener(); 384 installMetaDataListener(); 385 } 386 387 protected void installDataModelListener() { 388 dataModel.addValueChangeListener(new ValueChangeListener() { 389 public void valueChanged(ValueChangeEvent e) { 390 if (e.getFieldName().equals(fieldName) && 391 !pushing) { 392 pull(); 393 } 394 } 395 }); 396 } 397 398 399 404 protected void installMetaDataListener() { 405 } 416 417 } 418 | Popular Tags |