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 }