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     *   &lt;bean id=&quot;binderSelectionStrategy&quot;
023     *           class=&quot;org.springframework.richclient.form.binding.swing.SwingBinderSelectionStrategy&quot;&gt;
024     *       &lt;property name=&quot;bindersForPropertyTypes&quot;&gt;
025     *           &lt;map&gt;
026     *               &lt;entry&gt;
027     *                   &lt;key&gt;
028     *                       &lt;value type=&quot;java.lang.Class&quot;&gt;java.lang.Enum&lt;/value&gt;
029     *                   &lt;/key&gt;
030     *                   &lt;bean class=&quot;org.springframework.richclient.form.binding.swing.TigerEnumComboBoxBinder&quot; /&gt;
031     *               &lt;/entry&gt;
032     *           &lt;/map&gt;
033     *       &lt;/property&gt;
034     *   &lt;/bean&gt;
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    }