Announcement Announcement Module
Collapse
No announcement yet.
Enum binding not showing default Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Enum binding not showing default

    This is more or less a follow up on
    http://forum.springframework.org/showthread.php?t=17183

    The problem is that the default value of my enum property isn't showing up in my comboboxes when opening the form. The strange this is that they do save.

    context:
    Code:
        <bean id="conversionService"
                class="org.springframework.richclient.application.DefaultConversionService"/>
    
        <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
            <property name="targetObject">
                <ref local="conversionService"/>
            </property>
            <property name="targetMethod">
                <value>addConverters</value>
            </property>
            <property name="arguments">
                <list>
                    <list>
                        <bean class="be.kahosl.mammoet.swingclient.util.TigerEnumToText"/>
                        <bean class="be.kahosl.mammoet.swingclient.util.TextToTigerEnum"> <!-- TODO fix me to make targetClass for all Enums -->
                            <property name="targetClassList">
                                <list>
                                    <value type="java.lang.Class">be.kahosl.mammoet.model.order.OrderState</value>
                                    <value type="java.lang.Class">be.kahosl.mammoet.model.order.OrderParticipantState</value>
                                    <value type="java.lang.Class">be.kahosl.mammoet.model.order.FreightType</value>
                                </list>
                            </property>
                        </bean>
                    </list>
                </list>
            </property>
        </bean>
    Code:
    public class TextToTigerEnum extends AbstractConverter {
    
        private List<Class> targetClassList;
    
        private final boolean allowEmpty;
    
        public void setTargetClassList(List<Class> targetClassList) {
            this.targetClassList = targetClassList;
        }
    
        public TextToTigerEnum() {
            this(true);
        }
    
        protected TextToTigerEnum(boolean allowEmpty) {
            this.allowEmpty = allowEmpty;
        }
    
        public Class[] getSourceClasses() {
            return new Class[]{String.class};
        }
    
        public Class[] getTargetClasses() {
            return targetClassList.toArray(new Class[]{});
        }
    
        protected Object doConvert(Object source, Class targetClass) throws Exception {
            return (!allowEmpty || StringUtils.hasText((String) source)) ? Enum.valueOf(targetClass, (String) source) : null;
        }
    }
    Code:
    public class TigerEnumToText extends AbstractConverter {
    
        private boolean allowEmpty;
    
        public TigerEnumToText() {
            this(true);
        }
    
        protected TigerEnumToText(boolean allowEmpty) {
            this.allowEmpty = allowEmpty;
        }
    
        public Class[] getSourceClasses() {
            return new Class[]{Enum.class};
        }
    
        public Class[] getTargetClasses() {
            return new Class[]{String.class};
        }
    
        protected Object doConvert(Object source, Class targetClass) throws Exception {
            return (!allowEmpty || source != null) ? source.toString() : null;
        }
    }
    Code:
    public class TigerEnumComboBoxBinder extends ComboBoxBinder {
    
        protected TigerEnumComboBoxBinder() {
            super();
        }
    
    //    protected Binding doBind(JComponent control, FormModel formModel, String formPropertyPath, Map context) {
    //        Assert.isTrue(control instanceof JComboBox, formPropertyPath);
    //        ComboBoxBinding binding = new ComboBoxBinding((JComboBox)control, formModel, formPropertyPath);
    //        binding.setSelectableItemsHolder(new ValueHolder(theEnumValues));
    //        return binding;
    //    }
    
        protected Binding doBind(JComponent control, FormModel formModel, String formPropertyPath, Map context) {
            // TODO refactor and cache: see AbstractCachingLabeledEnumResolver
            // TODO i18n
            Assert.isTrue(control instanceof JComboBox, formPropertyPath);
            ComboBoxBinding binding = new ComboBoxBinding((JComboBox) control, formModel, formPropertyPath);
            applyContext(binding, context);
            binding.setSelectableItemsHolder(createEnumSelectableItemsHolder(formModel, formPropertyPath));
            return binding;
        }
    
        private ValueModel createEnumSelectableItemsHolder(FormModel formModel, String formPropertyPath) {
            Class propertyType = getPropertyType(formModel, formPropertyPath);
            Collection valueCollection = new ArrayList();
            Class<Enum> enumPropertyType = propertyType;
            Enum[] enumConstants = enumPropertyType.getEnumConstants();
            for (Enum enumConstant : enumConstants) {
                valueCollection.add(enumConstant.name());
            }
            Assert.notNull(valueCollection, "Unable to resolve enums for class '"
                    + getPropertyType(formModel, formPropertyPath).getName() + "'.");
            return new ValueHolder(valueCollection);
        }
    
    }

    For example my value object:
    Code:
    public class Freight extends PersistableObject {
    
        private FreightType freightType = FreightType.BULK; // combobox has all enum values but is empty to start (bad)
        private double weightInTon = 5.0; // starts on 5 (good)
    
        public Freight() {
        }
        //...
    }
    Last edited by robyn; May 14th, 2006, 08:15 PM.

  • #2
    I'm not sure if anybody is still interested in a solution to this problem, but since I didn't find an answer anywhere, I'll just answer it.
    The problem is, that the collection of selectable items is not built through the enum values, but through their string representation. That is why they fail the comparison with the object from the value model. See the addition in the code to hopefully understand what I'm trying to say. The toString() method of the enum will just call the name() method internally anyway, so that is no problem.

    Originally posted by ge0ffrey
    Code:
    public class TigerEnumComboBoxBinder extends ComboBoxBinder {
    
        protected TigerEnumComboBoxBinder() {
            super();
        }
    
    //    protected Binding doBind(JComponent control, FormModel formModel, String formPropertyPath, Map context) {
    //        Assert.isTrue(control instanceof JComboBox, formPropertyPath);
    //        ComboBoxBinding binding = new ComboBoxBinding((JComboBox)control, formModel, formPropertyPath);
    //        binding.setSelectableItemsHolder(new ValueHolder(theEnumValues));
    //        return binding;
    //    }
    
        protected Binding doBind(JComponent control, FormModel formModel, String formPropertyPath, Map context) {
            // TODO refactor and cache: see AbstractCachingLabeledEnumResolver
            // TODO i18n
            Assert.isTrue(control instanceof JComboBox, formPropertyPath);
            ComboBoxBinding binding = new ComboBoxBinding((JComboBox) control, formModel, formPropertyPath);
            applyContext(binding, context);
            binding.setSelectableItemsHolder(createEnumSelectableItemsHolder(formModel, formPropertyPath));
            return binding;
        }
    
        private ValueModel createEnumSelectableItemsHolder(FormModel formModel, String formPropertyPath) {
            Class propertyType = getPropertyType(formModel, formPropertyPath);
            Collection valueCollection = new ArrayList();
            Class<Enum> enumPropertyType = propertyType;
            Enum[] enumConstants = enumPropertyType.getEnumConstants();
            for (Enum enumConstant : enumConstants) {
    //            replace this line
    //            valueCollection.add(enumConstant.name());
    //            with the following one
                   valueCollection.add(enumConstant);
            }
            Assert.notNull(valueCollection, "Unable to resolve enums for class '"
                    + getPropertyType(formModel, formPropertyPath).getName() + "'.");
            return new ValueHolder(valueCollection);
        }
    
    }
    I have another problem though. I've tried to use the converters for the enum as described in other threads, but still only the name of my enum constant is displayed. This is not what I want, since the names of my enums are not how I want them to appear for the user. And it prohibits me from using i18n too. Does anybody else have this problem? My EnumToTextConverter is as follows:

    Code:
    public class EnumToTextConverter extends AbstractConverter {
    
    	private boolean allowEmpty;
    
    	public EnumToTextConverter() {
    		this(true);
    	}
    
    	protected EnumToTextConverter(boolean allowEmpty) {
    		this.allowEmpty = allowEmpty;
    	}
    
    	public Class[] getSourceClasses() {
    		return new Class[] { Enum.class };
    	}
    
    	public Class[] getTargetClasses() {
    		return new Class[] { String.class };
    	}
    
    	protected Object doConvert(Object source, Class targetClass)
    			throws Exception {		
    		return (!allowEmpty || source != null) ? "adf" : null;
    	}
    }
    Is there anything else I have to do? I also added it to the conversion service which is registered in my spring context. I am expecting to see my enum values converted to "adf", but they are still displayed with their name.

    Comment


    • #3
      That code above of me is obsolete.

      Here is an i18n tiger enum solution:

      http://opensource.atlassian.com/proj...browse/RCP-266

      +

      Code:
      package ggg.swingclient.util;
      
      import org.springframework.binding.form.FormModel;
      import org.springframework.binding.value.ValueModel;
      import org.springframework.binding.value.support.ValueHolder;
      import org.springframework.context.support.MessageSourceAccessor;
      import org.springframework.richclient.application.Application;
      import org.springframework.richclient.form.binding.Binding;
      import org.springframework.richclient.form.binding.swing.ComboBoxBinder;
      import org.springframework.richclient.form.binding.swing.ComboBoxBinding;
      import org.springframework.richclient.list.TextValueListRenderer;
      import org.springframework.util.Assert;
      
      import javax.swing.ComboBoxEditor;
      import javax.swing.JComponent;
      import java.awt.Component;
      import java.awt.event.ActionListener;
      import java.util.Map;
      
      /**
       * @author Benoit TODO replace username with real name
       * @author Geoffrey De Smet
       */
      public class TigerEnumComboBoxBinder extends ComboBoxBinder {
      
          protected TigerEnumComboBoxBinder() {
              super();
          }
      
          protected Binding doBind(JComponent control, FormModel formModel, String formPropertyPath, Map context) {
              ComboBoxBinding binding = (ComboBoxBinding)super.doBind(control, formModel, formPropertyPath, context);
              binding.setSelectableItemsHolder(createEnumSelectableItemsHolder(formModel, formPropertyPath));
              MessageSourceAccessor messageSourceAccessor = Application.services().getMessages();
              binding.setRenderer(new EnumListRenderer(messageSourceAccessor));
              binding.setEditor(new TigerEnumComboBoxEditor(messageSourceAccessor, binding.getEditor()));
              return binding;
          }
      
          private ValueModel createEnumSelectableItemsHolder(FormModel formModel, String formPropertyPath) {
              Class propertyType = getPropertyType(formModel, formPropertyPath);
              Class<Enum> enumPropertyType = propertyType;
              Enum[] enumConstants = enumPropertyType.getEnumConstants();
              return new ValueHolder(enumConstants);
          }
      
      
          public class EnumListRenderer extends TextValueListRenderer {
      
              private MessageSourceAccessor messageSourceAccessor;
      
              public EnumListRenderer(MessageSourceAccessor messageSourceAccessor) {
                  this.messageSourceAccessor = messageSourceAccessor;
              }
      
              protected String getTextValue(Object value) {
                  if (value == null) {
                      return "";
                  }
                  Enum valueEnum = (Enum) value;
                  Class<? extends Enum> valueClass = valueEnum.getClass();
                  return messageSourceAccessor.getMessage(valueClass.getName() + "." + valueEnum.name());
              }
      
          }
      
          public class TigerEnumComboBoxEditor implements ComboBoxEditor {
      
              private Object current;
      
              private MessageSourceAccessor messageSourceAccessor;
      
              private ComboBoxEditor inner;
      
              public TigerEnumComboBoxEditor(MessageSourceAccessor messageSourceAccessor, ComboBoxEditor editor) {
                  Assert.notNull(editor, "Editor cannot be null");
                  this.inner = editor;
                  this.messageSourceAccessor = messageSourceAccessor;
              }
      
              public void selectAll() {
                  inner.selectAll();
              }
      
              public Component getEditorComponent() {
                  return inner.getEditorComponent();
              }
      
              public void addActionListener(ActionListener l) {
                  inner.addActionListener(l);
              }
      
              public void removeActionListener(ActionListener l) {
                  inner.removeActionListener(l);
              }
      
              public Object getItem() {
                  return current;
              }
      
              public void setItem(Object value) {
                  current = value;
                  if (value != null) {
                      Enum valueEnum = (Enum) value;
                      Class<? extends Enum> valueClass = valueEnum.getClass();
                      inner.setItem(messageSourceAccessor.getMessage(valueClass.getName() + "." + valueEnum.name()));
                  }
                  else {
                      inner.setItem(null);
                  }
              }
          }
      
      }

      Comment


      • #4
        PS: Can anyone of the commiters apply RCP-266?

        Comment

        Working...
        X