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 org.springframework.binding.form.FormModel;
019    import org.springframework.binding.value.ValueModel;
020    import org.springframework.richclient.form.binding.Binding;
021    import org.springframework.richclient.form.binding.support.AbstractBinder;
022    import org.springframework.richclient.selection.binding.support.LabelProvider;
023    import org.springframework.richclient.selection.binding.support.SimpleSelectField;
024    
025    import javax.swing.JComponent;
026    import javax.swing.JLabel;
027    import javax.swing.ListCellRenderer;
028    import java.util.Comparator;
029    import java.util.Map;
030    
031    /**
032     * Binder for <code>SelectField</code>.
033     * <p>
034     * The context can contain the following items:
035     * <ul>
036     * <li><code>SELECTABLE_ITEMS_HOLDER_KEY</code>: The ValueModel holding the collection of selectable items</li>
037     * <li><code>LABEL_PROVIDER_KEY</code>: the label provider to provide the text of a given item</li>
038     * <li><code>FILTERED_KEY</code>: boolean value indicating whether the selection dialog will contain a filter field. If
039     * this value is <code>true</code> and the filter properties are not given, the string representation of the item will
040     * be used as filter value.</li>
041     * <li><code>FILTER_PROPERTIES_KEY</code>: array of properties that will be used for filtering</li>
042     * <li><code>RENDERER_KEY</code>: custom ListCellRenderer that will be used in the selection dialog</li>
043     * </ul>
044     * 
045     * @author Peter De Bruycker
046     */
047    public class ListSelectionDialogBinder extends AbstractBinder {
048    
049        public static final String SELECTABLE_ITEMS_HOLDER_KEY = "selectableItemsHolder";
050    
051        public static final String FILTER_PROPERTIES_KEY = "filterProperties";
052    
053        public static final String FILTERED_KEY = "filtered";
054    
055        public static final String RENDERER_KEY = "renderer";
056    
057        public static final String COMPARATOR_KEY = "comparator";
058    
059        public static final String LABEL_PROVIDER_KEY = "lavelProvider";
060    
061        public static final String DESCRIPTION_KEY_KEY = "descriptionKey";
062    
063        public static final String TITLE_KEY_KEY = "titleKey";
064    
065        public static final String NULLABLE_KEY = "nullable";
066    
067        private ValueModel selectableItemsHolder;
068    
069        private String[] filterProperties;
070        private boolean filtered;
071        private LabelProvider labelProvider;
072        private ListCellRenderer renderer;
073        private Comparator comparator;
074        private String descriptionKey;
075        private String titleKey;
076        private boolean nullable = true;
077    
078        public ListSelectionDialogBinder() {
079            super(null, new String[] { SELECTABLE_ITEMS_HOLDER_KEY, FILTER_PROPERTIES_KEY, FILTERED_KEY, RENDERER_KEY,
080                    LABEL_PROVIDER_KEY, COMPARATOR_KEY, DESCRIPTION_KEY_KEY, TITLE_KEY_KEY, NULLABLE_KEY });
081        }
082    
083        protected JComponent createControl(Map context) {
084            // not used
085            return new JLabel("dummy");
086        }
087    
088        protected void applyContext(ListSelectionDialogBinding binding, Map context) {
089            if (context.containsKey(SELECTABLE_ITEMS_HOLDER_KEY)) {
090                binding.setSelectableItemsHolder((ValueModel) context.get(SELECTABLE_ITEMS_HOLDER_KEY));
091            } else if (selectableItemsHolder != null) {
092                binding.setSelectableItemsHolder(selectableItemsHolder);
093            }
094    
095            if (context.containsKey(FILTER_PROPERTIES_KEY)) {
096                binding.setFilterProperties((String[]) context.get(FILTER_PROPERTIES_KEY));
097            } else if (filterProperties != null) {
098                binding.setFilterProperties(filterProperties);
099            }
100    
101            if (context.containsKey(FILTERED_KEY)) {
102                binding.setFiltered(((Boolean) context.get(FILTERED_KEY)).booleanValue());
103            } else if (filterProperties != null) {
104                binding.setFiltered(filtered);
105            }
106    
107            if (context.containsKey(RENDERER_KEY)) {
108                binding.setRenderer((ListCellRenderer) context.get(RENDERER_KEY));
109            } else if (renderer != null) {
110                binding.setRenderer(renderer);
111            }
112    
113            if (context.containsKey(COMPARATOR_KEY)) {
114                binding.setComparator((Comparator) context.get(COMPARATOR_KEY));
115            } else if (comparator != null) {
116                binding.setComparator(comparator);
117            }
118    
119            if (context.containsKey(LABEL_PROVIDER_KEY)) {
120                binding.setLabelProvider((LabelProvider) context.get(LABEL_PROVIDER_KEY));
121            } else if (labelProvider != null) {
122                binding.setLabelProvider(labelProvider);
123            }
124    
125            if (context.containsKey(DESCRIPTION_KEY_KEY)) {
126                binding.setDescriptionKey((String) context.get(DESCRIPTION_KEY_KEY));
127            } else if (descriptionKey != null) {
128                binding.setDescriptionKey(descriptionKey);
129            }
130    
131            if (context.containsKey(TITLE_KEY_KEY)) {
132                binding.setTitleKey((String) context.get(TITLE_KEY_KEY));
133            } else if (titleKey != null) {
134                binding.setTitleKey(titleKey);
135            }
136    
137            if (context.containsKey(NULLABLE_KEY)) {
138                binding.setNullable(((Boolean) context.get(NULLABLE_KEY)).booleanValue());
139            } else {
140                binding.setNullable(nullable);
141            }
142        }
143    
144        protected Binding doBind(JComponent notUsed, FormModel formModel, String formPropertyPath, Map context) {
145            ListSelectionDialogBinding binding = new ListSelectionDialogBinding(new SimpleSelectField(), formModel,
146                    formPropertyPath);
147            applyContext(binding, context);
148    
149            return binding;
150        }
151    
152        public void setSelectableItemsHolder(ValueModel selectableItemsHolder) {
153            this.selectableItemsHolder = selectableItemsHolder;
154        }
155    
156        public void setFilterProperties(String[] filterProperties) {
157            this.filterProperties = filterProperties;
158        }
159    
160        public void setFiltered(boolean filtered) {
161            this.filtered = filtered;
162        }
163    
164        public void setRenderer(ListCellRenderer renderer) {
165            this.renderer = renderer;
166        }
167    
168        public void setLabelProvider(LabelProvider labelProvider) {
169            this.labelProvider = labelProvider;
170        }
171    
172        public void setComparator(Comparator comparator) {
173            this.comparator = comparator;
174        }
175    
176        public void setDescriptionKey(String descriptionKey) {
177            this.descriptionKey = descriptionKey;
178        }
179    
180        public void setTitleKey(String titleKey) {
181            this.titleKey = titleKey;
182        }
183    
184        /**
185         * May return null if no value is set!
186         * 
187         * @return whether the field shall be nullable
188         */
189        public Boolean isNullable() {
190            return nullable;
191        }
192    
193        public void setNullable(Boolean nullable) {
194            this.nullable = nullable;
195        }
196    }