001: package com.silvermindsoftware.hitch.handlers.component;
002:
003: /**
004: * Copyright 2007 Brandon Goodin
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.lang.reflect.Method;
020:
021: public interface ComponentHandler<ComponentType, ModelType, UIType> {
022:
023: /**
024: * This method should check for certain conditions that determine whether population should
025: * even occur for this component.
026: * <p/>
027: * Example from JListComponentHandler:
028: * <code>
029: * <pre>
030: * public class JListComponentHandler
031: * extends AbstractComponentHandler<JList, Object, Object>
032: * implements ComponentHandler<JList, Object, Object> {
033: * ...
034: * public boolean isPopulateHandleable(JList component, Object modelPropertyValue) {
035: * return modelPropertyValue != null;
036: * }
037: * ...
038: * }
039: * </pre>
040: * </code>
041: *
042: * @param component
043: * @param modelPropertyValue
044: * @return
045: */
046: public boolean isPopulateHandleable(ComponentType component,
047: ModelType modelPropertyValue);
048:
049: /**
050: * This method should check for certain conditions that determine whether an update of the model
051: * should even occur from this component. There is currently no scenario in hitch where this is
052: * required. It was added as a counterpart to #isPopulateHandleable in the anticipation that it
053: * may be useful for developers who create custom component handlers.
054: *
055: * @param component
056: * @return
057: */
058: public boolean isUpdateHandleable(ComponentType component);
059:
060: /**
061: * This is the name of the method that retrieves the value from the component. The
062: * method name should be spelled out completely. For example if the component is
063: * JTextField this method would return "getText". If the occasion ever requires it
064: * you may pass different values back from this method @see #getComponentSetter for
065: * example.
066: *
067: * @param component
068: * @return
069: */
070: public Method getComponentGetter(ComponentType component);
071:
072: /**
073: * This is the name of the method that sets the value on the component. The
074: * method name should be spelled out completely. For example if the component is
075: * JTextField this method would return "setText". If the occasion ever requires it
076: * you may pass different values back from this method @see JComboBoxComponentHandler#getSetterName.
077: * <p/>
078: * Example from JComboBoxComponentHandler
079: * <p/>
080: * <code>
081: * <pre>
082: * public class JComboBoxComponentHandler
083: * extends AbstractComponentHandler<JComboBox, Object, Object>
084: * implements ComponentHandler<JComboBox, Object, Object>
085: * {
086: * ...
087: * protected String getSetterName() {
088: * if (compareProperties != null && compareProperties.length > 0) {
089: * return "setSelectedIndex";
090: * } else {
091: * return "setSelectedItem";
092: * }
093: * ...
094: * }
095: * </pre>
096: * </code>
097: *
098: * @param component
099: * @return
100: */
101: public Method getComponentSetter(ComponentType component);
102:
103: /**
104: * <h1><b>
105: * Right up front let's make it clear that you should not use this method for performing type conversion
106: * </b></h1>
107: * <p/>
108: * This method is meant to massage existing data into a state that can be converted. Let's
109: * take a look at the TextComponentHandler. You can see that the TextComponentHandler examines
110: * if the modelPropertyValue is null and if it is alters it's representation to an empty String.
111: * The reason for this is that JTextField will display a null as 'null' and that is undesireable.
112: * It would not be appropriate to deal with this in a TypeHandler. For a more complex example you
113: * can take a look at the @see JComboBoxComponentHandler#preProcessPopulate which is a very
114: * involved implementation.
115: * <p/>
116: * <b>TextComponent Handler Example</b><br/>
117: * <code>
118: * <pre>
119: * public class TextComponentHandler
120: * extends AbstractComponentHandler<JComponent, Object, Object>
121: * implements ComponentHandler<JComponent, Object, Object>
122: * {
123: * ...
124: * public Object preProcessPopulate(JComponent component, Object modelPropertyValue) {
125: * return modelPropertyValue == null ? "" : modelPropertyValue;
126: * }
127: * ...
128: * }
129: * </pre>
130: * </code>
131: *
132: * @param component
133: * @param modelPropertyValue
134: * @return
135: */
136: public UIType preProcessPopulate(ComponentType component,
137: ModelType modelPropertyValue);
138:
139: /**
140: * <h1><b>
141: * Right up front let's make it clear that you should not use this method for performing type conversion
142: * </b></h1>
143: * <p/>
144: * Just like @see #preProcessPopulate the preProcessUpdate method is meant to massage data
145: * into a state that can be converted.
146: * </p>
147: * Following is an example of preProcessUpdate as used in the JListComponentHandler
148: * <code>
149: * <pre>
150: * public class JListComponentHandler
151: * extends AbstractComponentHandler<JList, Object, Object>
152: * implements ComponentHandler<JList, Object, Object> {
153: * ...
154: * public Object preProcessUpdate(JList component, Object formFieldValue) {
155: * // if a single selection return a single object
156: * if (component.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) {
157: * Object[] selectedValues = (Object[]) formFieldValue;
158: * if (selectedValues.length == 0) {
159: * return null;
160: * } else {
161: * return selectedValues[0];
162: * }
163: * } else {
164: * //otherwise return an array
165: * return formFieldValue;
166: * }
167: * }
168: * ...
169: * }
170: * </pre>
171: * </code>
172: *
173: * @param component
174: * @param modelPropertyValue
175: * @return
176: */
177: public ModelType preProcessUpdate(ComponentType component,
178: UIType modelPropertyValue);
179:
180: /**
181: * This method handles post processing of a populate. There is currently no scenario in hitch
182: * where this is required. It was added as a counterpart to #preProcessPopulate in the
183: * anticipation that it may be useful for developers who create custom component handlers.
184: *
185: * @param component
186: */
187: public void postProcessPopulate(ComponentType component);
188:
189: /**
190: * This method handles post processing of an update. There is currently no scenario in hitch
191: * where this is required. It was added as a counterpart to #preProcessUpdate in the
192: * anticipation that it may be useful for developers who create custom component handlers.
193: *
194: * @param component
195: */
196: public void postProcessUpdate(ComponentType component);
197:
198: /**
199: * This method provides the default read only state for this component. For example, the
200: * JLabel is generally used as a read only component so its default is set to true.
201: * <p/>
202: * <code>
203: * <pre>
204: * public class JLabelComponentHandler extends TextComponentHandler {
205: * public boolean getDefaultReadOnly() {
206: * return true;
207: * }
208: * }
209: * </pre>
210: * </code>
211: *
212: * @return
213: */
214: public boolean getDefaultReadOnly();
215:
216: }
|