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.binding.support;
017
018 import java.beans.PropertyChangeEvent;
019 import java.beans.PropertyChangeListener;
020
021 import org.springframework.binding.form.FormModel;
022
023 /**
024 * A helper implementation for binding to custom controls.
025 *
026 * @author Oliver Hutchison
027 */
028 public abstract class CustomBinding extends AbstractBinding {
029
030 private final ValueModelChangeHandler valueModelChangeHandler;
031
032 /** Possible forced read-only. */
033 private boolean readOnly = false;
034
035 protected CustomBinding(FormModel formModel, String formPropertyPath, Class requiredSourceClass) {
036 super(formModel, formPropertyPath, requiredSourceClass);
037 valueModelChangeHandler = new ValueModelChangeHandler();
038 getValueModel().addValueChangeListener(valueModelChangeHandler);
039 }
040
041 /**
042 * Called when the underlying property's value model value changes.
043 */
044 protected abstract void valueModelChanged(Object newValue);
045
046 /**
047 * Should be called when the bound component's value changes.
048 */
049 protected final void controlValueChanged(Object newValue) {
050 getValueModel().setValueSilently(newValue, valueModelChangeHandler);
051 }
052
053 private class ValueModelChangeHandler implements PropertyChangeListener {
054 public void propertyChange(PropertyChangeEvent evt) {
055 if (logger.isDebugEnabled()) {
056 logger.debug("Notifying binding of value model value changed");
057 }
058 valueModelChanged(getValue());
059 }
060 }
061
062 /**
063 * Force this binding to be readonly, whatever the metaInfo.
064 *
065 * @param readOnly <code>true</code> if only read-access should be allowed.
066 */
067 public void setReadOnly(boolean readOnly)
068 {
069 this.readOnly = readOnly;
070 readOnlyChanged();
071 }
072
073 /**
074 * We were using an override to check the setter's visibility on the backing object.
075 */
076 @Override
077 protected boolean isReadOnly()
078 {
079 return this.readOnly || super.isReadOnly();
080 }
081 }