001: package com.silvermindsoftware.hitch.handlers.component;
002:
003: import javax.swing.*;
004:
005: /**
006: * Copyright 2007 Brandon Goodin
007: * <p/>
008: * Licensed under the Apache License, Version 2.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: * <p/>
012: * http://www.apache.org/licenses/LICENSE-2.0
013: * <p/>
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: */
020:
021: public class JComboBoxComponentHandler extends
022: AbstractComponentHandler<JComboBox, Object, Object> implements
023: ComponentHandler<JComboBox, Object, Object> {
024:
025: // internal reflection lookup variables
026: private String valueProperty;
027: private String[] compareProperties;
028:
029: protected Class getSetterParameterType() {
030: if (compareProperties != null && compareProperties.length > 0) {
031: return int.class;
032: } else {
033: return Object.class;
034: }
035: }
036:
037: /**
038: * Selection of an item can happen in a couple ways:
039: * <ol>
040: * <li>
041: * Use compareProperties to specify properties that are examined to determine equality between the
042: * JComboBox item and the model object property. If the model object property is a primitive or
043: * first class object the compareProperties are only used to lookup properties on the JComboBox item.
044: * </li>
045: * <li>
046: * Allow the JComboBox to naturally select the appropriate item. You can accomplish this by
047: * not declaring any compareProperties. If you opt to do this you will need to override equals and hashcode
048: * on more complex object in order to guarantee equality. With primitives or first class object it should
049: * select without need of alteration
050: * </li>
051: * </ol>
052: *
053: * @param component - the component we are populating
054: * @param modelPropertyValue - the value we are populating it with
055: * @return the value that is needed by the component
056: */
057: public Object preProcessPopulate(JComboBox component,
058: Object modelPropertyValue) {
059: // if compareProperties have values then use them to select the proper Index
060: if (modelPropertyValue == null) {
061: return 0;
062: } else if (compareProperties != null
063: && compareProperties.length > 0) {
064:
065: int selectedIndex = -1;
066: //iterate model
067: ComboBoxModel cbm = component.getModel();
068: for (int index = 0; index < cbm.getSize(); index++) {
069: Object item = cbm.getElementAt(index);
070: boolean isEqual = true;
071: for (String property : compareProperties) {
072:
073: // get value on current element
074: Object comboBoxItem = getPropertyValue(item,
075: property);
076:
077: // if model object is prmitive 1st class compare
078: if (isBaseType(modelPropertyValue)) {
079: if (comboBoxItem == null) {
080: // todo: we are in the else part of if(modelPropertyValue == null)
081: // todo: this is never null
082: // if (modelPropertyValue != null) {
083: isEqual = false;
084: break;
085: // }
086: } else if (!comboBoxItem
087: .equals(modelPropertyValue)) {
088: isEqual = false;
089: break;
090: }
091: } else {
092: // otherwise find the property
093:
094: Object nestedPropertyValue = getPropertyValue(
095: modelPropertyValue, property);
096:
097: // compare
098: if (comboBoxItem == null) {
099: if (nestedPropertyValue != null) {
100: isEqual = false;
101: break;
102: }
103: } else if (!comboBoxItem
104: .equals(nestedPropertyValue)) {
105: isEqual = false;
106: break;
107: }
108:
109: }
110:
111: }
112:
113: if (isEqual) {
114: selectedIndex = index;
115: break;
116: }
117:
118: }
119:
120: return selectedIndex;
121:
122: } else
123:
124: {
125: // otherwise just set the object
126: return modelPropertyValue;
127: }
128: }
129:
130: /**
131: * If the selected item in the JCombo box is not the desired value to be set on the
132: * model object property, you can use the valueProperty to specify a property on the JComboBox
133: * selected item that will be used as the value that is set on the model object property.
134: */
135: public Object preProcessUpdate(JComboBox component,
136: Object componentValue) {
137: return getPropertyValue(componentValue, valueProperty);
138: }
139:
140: protected String getGetterName() {
141: return "getSelectedItem";
142: }
143:
144: protected String getSetterName() {
145: if (compareProperties != null && compareProperties.length > 0) {
146: return "setSelectedIndex";
147: } else {
148: return "setSelectedItem";
149: }
150: }
151:
152: public void setCompareProperties(String compareProperties) {
153: this .compareProperties = compareProperties.split(",");
154: }
155:
156: public void setValueProperty(String valueProperty) {
157: this.valueProperty = valueProperty;
158: }
159: }
|