001 /*
002 * Copyright 2002-2008 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.selection.binding;
017
018 import java.beans.PropertyChangeEvent;
019 import java.beans.PropertyChangeListener;
020 import java.util.Collections;
021 import java.util.Comparator;
022
023 import javax.swing.JComponent;
024 import javax.swing.ListCellRenderer;
025
026 import org.springframework.binding.form.FormModel;
027 import org.springframework.binding.value.ValueModel;
028 import org.springframework.richclient.dialog.ApplicationDialog;
029 import org.springframework.richclient.form.binding.support.CustomBinding;
030 import org.springframework.richclient.selection.binding.support.LabelProvider;
031 import org.springframework.richclient.selection.binding.support.LabelProviderListCellRenderer;
032 import org.springframework.richclient.selection.binding.support.SelectField;
033 import org.springframework.richclient.selection.binding.support.ValueModel2EventListBridge;
034 import org.springframework.richclient.selection.dialog.FilterListSelectionDialog;
035 import org.springframework.richclient.selection.dialog.ListSelectionDialog;
036 import org.springframework.rules.closure.Closure;
037 import org.springframework.rules.closure.support.Block;
038 import org.springframework.util.StringUtils;
039
040 import ca.odell.glazedlists.EventList;
041 import ca.odell.glazedlists.FilterList;
042 import ca.odell.glazedlists.GlazedLists;
043 import ca.odell.glazedlists.SortedList;
044 import ca.odell.glazedlists.impl.beans.BeanTextFilterator;
045 import ca.odell.glazedlists.impl.filter.StringTextFilterator;
046
047 /**
048 * Binding for selection objects in a form.
049 *
050 * @author Peter De Bruycker
051 */
052 public class ListSelectionDialogBinding extends CustomBinding {
053
054 protected SelectField selectField;
055 private boolean filtered;
056 private String[] filterProperties;
057 private ListCellRenderer renderer;
058 private ValueModel selectableItemsHolder;
059 private LabelProvider labelProvider;
060 private Comparator comparator;
061 private String descriptionKey;
062 private String titleKey;
063 private boolean nullable = true;
064
065 protected ListSelectionDialogBinding(SelectField selectField, FormModel formModel, String formPropertyPath) {
066 super(formModel, formPropertyPath, null);
067 this.selectField = selectField;
068 }
069
070 protected JComponent doBindControl() {
071 selectField.setLabelProvider(labelProvider);
072 selectField.setSelectionDialog(createSelectionDialog());
073
074 selectField.setNullable(nullable);
075
076 // trigger control creation so we can set the value
077 selectField.getControl();
078
079 selectField.setValue(getValue());
080
081 selectField.addPropertyChangeListener("value", new PropertyChangeListener() {
082 public void propertyChange(PropertyChangeEvent evt) {
083 controlValueChanged(selectField.getValue());
084 }
085 });
086
087 return selectField.getControl();
088 }
089
090 protected ApplicationDialog createSelectionDialog() {
091 EventList eventList = createEventList(selectableItemsHolder);
092 final ValueModel2EventListBridge itemRefresher = new ValueModel2EventListBridge(selectableItemsHolder,
093 eventList, true);
094
095 ListSelectionDialog selectionDialog = null;
096 if (filtered) {
097 FilterListSelectionDialog filterDialog = new FilterListSelectionDialog("", null, new FilterList(eventList));
098 if (filterProperties == null) {
099 filterDialog.setFilterator(new StringTextFilterator());
100 } else {
101 filterDialog.setFilterator(new BeanTextFilterator(filterProperties));
102 }
103
104 selectionDialog = filterDialog;
105 } else {
106 selectionDialog = new ListSelectionDialog("", null, eventList);
107 }
108
109 selectionDialog.setOnAboutToShow(new Block() {
110 protected void handle(Object ignore) {
111 itemRefresher.synchronize();
112 }
113 });
114
115 selectionDialog.setOnSelectAction(new Closure() {
116 public Object call(Object argument) {
117 controlValueChanged(argument);
118 selectField.setValue(argument);
119
120 return argument;
121 }
122 });
123 selectionDialog.setRenderer(getRendererForSelectionDialog());
124
125 if (StringUtils.hasText(descriptionKey)) {
126 String description = getMessage(descriptionKey);
127 selectionDialog.setDescription(description);
128 }
129 if (StringUtils.hasText(titleKey)) {
130 String title = getMessage(titleKey);
131 selectionDialog.setTitle(title);
132 }
133
134 return selectionDialog;
135 }
136
137 private EventList createEventList(ValueModel selectableItemsHolder) {
138 EventList eventList = GlazedLists.eventList(Collections.emptyList());
139
140 if (comparator != null) {
141 eventList = new SortedList(eventList, comparator);
142 }
143
144 return eventList;
145 }
146
147 protected ListCellRenderer getRendererForSelectionDialog() {
148 if (renderer != null) {
149 return renderer;
150 }
151
152 if (labelProvider != null) {
153 return new LabelProviderListCellRenderer(labelProvider);
154 }
155
156 return null;
157 }
158
159 protected void enabledChanged() {
160 selectField.setEnabled(isEnabled());
161 }
162
163 protected void readOnlyChanged() {
164 selectField.setEditable(!isReadOnly());
165 }
166
167 public void setLabelProvider(LabelProvider provider) {
168 this.labelProvider = provider;
169 }
170
171 protected void valueModelChanged(Object newValue) {
172 selectField.setValue(newValue);
173 }
174
175 public void setFilterProperties(String[] filterProperties) {
176 this.filterProperties = filterProperties;
177 }
178
179 public void setFiltered(boolean filtered) {
180 this.filtered = filtered;
181 }
182
183 public void setRenderer(ListCellRenderer renderer) {
184 this.renderer = renderer;
185 }
186
187 public void setSelectableItemsHolder(ValueModel selectableItemsHolder) {
188 this.selectableItemsHolder = selectableItemsHolder;
189 }
190
191 public void setComparator(Comparator comparator) {
192 this.comparator = comparator;
193 }
194
195 public void setDescriptionKey(String descriptionKey) {
196 this.descriptionKey = descriptionKey;
197 }
198
199 public void setTitleKey(String titleKey) {
200 this.titleKey = titleKey;
201 }
202
203 public void setNullable(boolean nullable) {
204 this.nullable = nullable;
205 }
206 }