001    package org.springframework.richclient.form.binding.swing;
002    
003    import java.awt.Component;
004    import java.awt.event.ActionListener;
005    
006    import javax.swing.ComboBoxEditor;
007    import javax.swing.JComponent;
008    
009    import org.springframework.binding.form.FormModel;
010    import org.springframework.context.support.MessageSourceAccessor;
011    import org.springframework.richclient.list.TextValueListRenderer;
012    import org.springframework.util.Assert;
013    
014    /**
015     * Binds a Tiger enum in a combobox and supports i18n.<br/> The i18n key of an enum is the full classname + "." +
016     * enumfield.<br/> For example:<br/> x.y.Season.WINTER = Winter<br/>
017     * <p>
018     * configuration happens like this:
019     * </p>
020     *
021     * <pre>
022     *   <bean id="binderSelectionStrategy"
023     *           class="org.springframework.richclient.form.binding.swing.SwingBinderSelectionStrategy">
024     *       <property name="bindersForPropertyTypes">
025     *           <map>
026     *               <entry>
027     *                   <key>
028     *                       <value type="java.lang.Class">java.lang.Enum</value>
029     *                   </key>
030     *                   <bean class="org.springframework.richclient.form.binding.swing.TigerEnumComboBoxBinder" />
031     *               </entry>
032     *           </map>
033     *       </property>
034     *   </bean>
035     * </pre>
036     *
037     * @author Geoffrey De Smet
038     */
039    public class EnumComboBoxBinder extends ComboBoxBinder {
040    
041        public EnumComboBoxBinder() {
042            super();
043        }
044    
045        protected AbstractListBinding createListBinding(JComponent control, FormModel formModel, String formPropertyPath) {
046            ComboBoxBinding binding = (ComboBoxBinding) super.createListBinding(control, formModel, formPropertyPath);
047            binding.setSelectableItems(createEnumSelectableItems(formModel, formPropertyPath));
048            MessageSourceAccessor messageSourceAccessor = getMessages();
049            binding.setRenderer(new EnumListRenderer(messageSourceAccessor));
050            binding.setEditor(new EnumComboBoxEditor(messageSourceAccessor, binding.getEditor()));
051            return binding;
052        }
053    
054        protected Enum[] createEnumSelectableItems(FormModel formModel, String formPropertyPath) {
055            Class propertyType = getPropertyType(formModel, formPropertyPath);
056            Class<Enum> enumPropertyType = propertyType;
057            return enumPropertyType.getEnumConstants();
058        }
059    
060        public class EnumListRenderer extends TextValueListRenderer {
061    
062            private MessageSourceAccessor messageSourceAccessor;
063    
064            public EnumListRenderer(MessageSourceAccessor messageSourceAccessor) {
065                this.messageSourceAccessor = messageSourceAccessor;
066            }
067    
068            protected String getTextValue(Object value) {
069                if (value == null) {
070                    return "";
071                }
072                Enum valueEnum = (Enum) value;
073                Class<? extends Enum> valueClass = valueEnum.getClass();
074                return messageSourceAccessor.getMessage(valueClass.getName() + "." + valueEnum.name());
075            }
076    
077        }
078    
079        public class EnumComboBoxEditor implements ComboBoxEditor {
080    
081            private Object current;
082    
083            private MessageSourceAccessor messageSourceAccessor;
084    
085            private ComboBoxEditor inner;
086    
087            public EnumComboBoxEditor(MessageSourceAccessor messageSourceAccessor, ComboBoxEditor editor) {
088                Assert.notNull(editor, "Editor cannot be null");
089                this.inner = editor;
090                this.messageSourceAccessor = messageSourceAccessor;
091            }
092    
093            public void selectAll() {
094                inner.selectAll();
095            }
096    
097            public Component getEditorComponent() {
098                return inner.getEditorComponent();
099            }
100    
101            public void addActionListener(ActionListener l) {
102                inner.addActionListener(l);
103            }
104    
105            public void removeActionListener(ActionListener l) {
106                inner.removeActionListener(l);
107            }
108    
109            public Object getItem() {
110                return current;
111            }
112    
113            public void setItem(Object value) {
114                current = value;
115                if (value != null) {
116                    Enum valueEnum = (Enum) value;
117                    Class<? extends Enum> valueClass = valueEnum.getClass();
118                    inner.setItem(messageSourceAccessor.getMessage(valueClass.getName() + "." + valueEnum.name()));
119                } else {
120                    inner.setItem(null);
121                }
122            }
123        }
124    
125    }