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 }