001    /*
002     * Copyright 2002-2004 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of 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,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.springframework.richclient.form.binding.swing;
017    
018    import java.util.Map;
019    
020    import javax.swing.ComboBoxEditor;
021    import javax.swing.JComboBox;
022    import javax.swing.JComponent;
023    import javax.swing.ListCellRenderer;
024    
025    import org.springframework.binding.form.FormModel;
026    import org.springframework.rules.closure.Closure;
027    import org.springframework.util.Assert;
028    
029    /**
030     * @author Oliver Hutchison
031     */
032    public class ComboBoxBinder extends AbstractListBinder {
033        public static final String RENDERER_KEY = "renderer";
034    
035        public static final String EDITOR_KEY = "editor";
036    
037        /**
038         * context key for a value which is used to mark an empty Selection. If this value is selected null will be assigned
039         * to the fields value
040         */
041        public static final String EMPTY_SELECTION_VALUE = "emptySelectionValue";
042    
043        private Object renderer;
044    
045        private Object editor;
046    
047        private Object emptySelectionValue;
048    
049        public ComboBoxBinder() {
050            this(null, new String[] { SELECTABLE_ITEMS_KEY, COMPARATOR_KEY, RENDERER_KEY, EDITOR_KEY, FILTER_KEY,
051                    EMPTY_SELECTION_VALUE });
052        }
053    
054        public ComboBoxBinder(String[] supportedContextKeys) {
055            this(null, supportedContextKeys);
056        }
057    
058        public ComboBoxBinder(Class requiredSourceClass, String[] supportedContextKeys) {
059            super(requiredSourceClass, supportedContextKeys);
060        }
061    
062        protected AbstractListBinding createListBinding(JComponent control, FormModel formModel, String formPropertyPath) {
063            Assert.isInstanceOf(JComboBox.class, control, formPropertyPath);
064            return new ComboBoxBinding((JComboBox) control, formModel, formPropertyPath, getRequiredSourceClass());
065        }
066    
067        protected void applyContext(AbstractListBinding binding, Map context) {
068            super.applyContext(binding, context);
069            ComboBoxBinding comboBoxBinding = (ComboBoxBinding) binding;
070            if (context.containsKey(RENDERER_KEY)) {
071                comboBoxBinding.setRenderer((ListCellRenderer) decorate(context.get(RENDERER_KEY), comboBoxBinding
072                        .getRenderer()));
073            } else if (renderer != null) {
074                comboBoxBinding.setRenderer((ListCellRenderer) decorate(renderer, comboBoxBinding.getRenderer()));
075            }
076            if (context.containsKey(EDITOR_KEY)) {
077                comboBoxBinding.setEditor((ComboBoxEditor) decorate(context.get(EDITOR_KEY), comboBoxBinding.getEditor()));
078            } else if (editor != null) {
079                comboBoxBinding.setEditor((ComboBoxEditor) decorate(editor, comboBoxBinding.getEditor()));
080            }
081            if (context.containsKey(EMPTY_SELECTION_VALUE)) {
082                comboBoxBinding.setEmptySelectionValue(context.get(EMPTY_SELECTION_VALUE));
083            } else if (emptySelectionValue != null) {
084                comboBoxBinding.setEmptySelectionValue(emptySelectionValue);
085            }
086        }
087    
088        protected JComponent createControl(Map context) {
089            return getComponentFactory().createComboBox();
090        }
091    
092        public void setRenderer(ListCellRenderer renderer) {
093            this.renderer = renderer;
094        }
095    
096        /**
097         * Defines a closure which is called to create the renderer. The argument for the closure will be the default
098         * renderer (see {@link JComboBox#getRenderer()} of the combobox. The closure must create an instance of
099         * {@link ListCellRenderer}
100         * 
101         * @param rendererClosure
102         *            the closure which is used to create the renderer
103         */
104        public void setRendererClosure(Closure rendererClosure) {
105            this.renderer = rendererClosure;
106        }
107    
108        public void setEditor(ComboBoxEditor editor) {
109            this.editor = editor;
110        }
111    
112        /**
113         * Defines a closure which is called to create the editor. The argument for the closure will be the default editor
114         * (see {@link JComboBox#getEditor()} of the combobox. The closure must create an instance of {@link ComboBoxEditor}
115         * 
116         * @param editorClosure
117         *            the closure which is used to create the editor
118         */
119        public void setEditorClosure(Closure editorClosure) {
120            this.editor = editorClosure;
121        }
122    
123        public Object getEmptySelectionValue() {
124            return emptySelectionValue;
125        }
126    
127        public void setEmptySelectionValue(Object emptySelectionValue) {
128            this.emptySelectionValue = emptySelectionValue;
129        }
130    }