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.list;
017
018 import java.beans.PropertyChangeEvent;
019 import java.beans.PropertyChangeListener;
020 import java.util.Collection;
021 import java.util.List;
022
023 import org.apache.commons.logging.Log;
024 import org.apache.commons.logging.LogFactory;
025 import org.springframework.binding.value.ValueModel;
026 import org.springframework.binding.value.support.ValueHolder;
027
028 /**
029 * A combobox whose contents are dynamically refreshable.
030 *
031 * @author Keith Donald
032 */
033 public class DynamicComboBoxListModel extends ComboBoxListModel implements PropertyChangeListener {
034
035 private static final Log logger = LogFactory.getLog(DynamicComboBoxListModel.class);
036
037 private final SelectedItemChangeHandler selectedItemChangeHandler = new SelectedItemChangeHandler();
038
039 private final ValueModel selectedItemHolder;
040
041 private ValueModel selectableItemsHolder;
042
043 public DynamicComboBoxListModel(ValueModel selectedItemHolder) {
044 this(selectedItemHolder, (ValueModel)null);
045 }
046
047 public DynamicComboBoxListModel(ValueModel selectedItemHolder, List items) {
048 this(selectedItemHolder, new ValueHolder(items));
049 }
050
051 public DynamicComboBoxListModel(ValueModel selectedItemHolder, ValueModel selectableItemsHolder) {
052 this.selectedItemHolder = selectedItemHolder;
053 if (selectedItemHolder != null) {
054 selectedItemHolder.addValueChangeListener(selectedItemChangeHandler);
055 }
056 setSelectableItemsHolder(selectableItemsHolder);
057 }
058
059 public void setSelectableItemsHolder(ValueModel holder) {
060 if (this.selectableItemsHolder == holder) {
061 return;
062 }
063 if (this.selectableItemsHolder != null) {
064 holder.removeValueChangeListener(this);
065 }
066 this.selectableItemsHolder = holder;
067 if (this.selectableItemsHolder != null) {
068 doAdd(holder.getValue());
069 this.selectableItemsHolder.addValueChangeListener(this);
070 }
071 }
072
073 public Object getSelectedItem() {
074 if (selectedItemHolder != null) {
075 if (logger.isDebugEnabled()) {
076 logger.debug("Returning selected item " + selectedItemHolder.getValue());
077 }
078 return selectedItemHolder.getValue();
079 }
080
081 return super.getSelectedItem();
082 }
083
084 public void setSelectedItem(Object selectedItem) {
085 if (selectedItemHolder != null) {
086 if (logger.isDebugEnabled()) {
087 logger.debug("Setting newly selected item on value holder to " + selectedItem);
088 }
089 selectedItemHolder.setValue(selectedItem);
090 }
091 else {
092 super.setSelectedItem(selectedItem);
093 }
094 }
095
096 public void propertyChange(PropertyChangeEvent evt) {
097 if (logger.isDebugEnabled()) {
098 logger.debug("Backing collection of selectable items changed; "
099 + "refreshing combo box with contents of new collection.");
100 }
101 doAdd(selectableItemsHolder.getValue());
102 }
103
104 private void doAdd(Object items) {
105 clear();
106 if (items != null) {
107 if (items instanceof Collection) {
108 addAll((Collection)items);
109 }
110 else if (items instanceof Object[]) {
111 Object[] itemsArray = (Object[])items;
112 for (int i = 0; i < itemsArray.length; i++) {
113 add(itemsArray[i]);
114 }
115 }
116 else {
117 throw new IllegalArgumentException("selectableItemsHolder must hold a Collection or array");
118 }
119 }
120 sort();
121 }
122
123 private class SelectedItemChangeHandler implements PropertyChangeListener {
124
125 public void propertyChange(PropertyChangeEvent evt) {
126 if (logger.isDebugEnabled()) {
127 logger.debug("Notifying combo box view selected value changed; new value is '"
128 + selectedItemHolder.getValue() + "'");
129 }
130 /*
131 if (selectedItemHolder.getValue() == null) {
132 if (size() > 0 && get(0) != null) {
133 if (logger.isDebugEnabled()) {
134 logger
135 .debug("Backing value model is null; Pre-setting initial value to first combo-box element "
136 + get(0));
137 }
138 setSelectedItem(get(0));
139 }
140 }
141 else {
142 */
143 if (logger.isDebugEnabled()) {
144 logger.debug("Firing contents change event; selected item may have changed");
145 }
146 fireContentsChanged(this, -1, -1);
147 if (logger.isDebugEnabled()) {
148 logger.debug("Fired contents change event!");
149 }
150 //}
151 }
152 }
153
154 }