Oops Null Pointer

Java programming related

Monthly Archives: April 2011

GXT Enums, ComboBoxes and i18n

If you want to have a ComboBox that uses enums with i18n you can use a SimpleComboBox and use the enums toString() method to return the GWT i18n constants.

As I posted on the GXT forums, I don’t want to use toString() as I want the enum to still work on the server side (say during debugging).

Instead I have a getLabel() method and want the GXT ComboBox to call that. Here’s the code:

It does the following:

  • Convert the value in the ComboBox with a property editor to call getLabel()
  • Convert the values in the list with a ModelProcessor to call getLabel() and Template
  • The Enum

    public enum Condition {
      New,
      Used,
      Damaged
    
      public String getLabel()
      {
          // get i18n with a GWT create call save via a ConstantsWithLookup
      }
    }
    

    The ComboBox that uses Condition enum (with a getLabel() method for i18n)

    final SimpleComboBox<Condition> combo = new SimpleComboBox<Condition>();
    combo.setFieldLabel("Condition");
    combo.setName("condition");
    combo.add(Arrays.asList(Condition.values()));        
    combo.setEditable(false);
    combo.setAllowBlank(false);
    combo.setTriggerAction(TriggerAction.ALL);
    combo.setSimpleValue(Condition.NEW);
    

    The standard enum field binding:

    FieldBinding binding = new FieldBinding(combo, "condition") 
    {
        @SuppressWarnings("unchecked")
        @Override
        protected Object onConvertFieldValue(Object value) {
            return ((SimpleComboValue<Condition>)value).getValue();
        }
    
        @Override
        protected Object onConvertModelValue(Object value) {
            return combo.findModel((Condition)value);
        }
    };
    formBinding.addFieldBinding(binding);
    

    The rest (pretty ugly but it works)

    // Replace the text in the box with the enums label
    ListModelPropertyEditor<SimpleComboValue<Condition>> propEditor = 
        new ListModelPropertyEditor<SimpleComboValue<Condition>>()
        {
             public String getStringValue(SimpleComboValue<Condition> value) {
                 return value.getValue().getLabel();
             }
        };
    
    propEditor.setDisplayProperty("label");
    combo.setPropertyEditor(propEditor);
            
    // Replace the text in the list with the enums labels
    combo.getView().setModelProcessor(new ModelProcessor<SimpleComboValue<Condition>>() 
    {
        public SimpleComboValue<Condition> prepareData(SimpleComboValue<Condition> model) 
        {
            model.set("label", model.getValue().getLabel());
            return model;
        }
    });
            
    // Use label property in list as SimpleComboBox displayProperty "value" is used by default
    String html = "<tpl for=\".\"><div role=\"listitem\" class=\"" + combo.getListStyle() + "-item\">{" + "label" + "}</div></tpl>";
    combo.setTemplate(html);
    

    If all used enums implemented a “Labelable” (or Internationalisable?) interface that required the getLabel() method then this code could be reused for different enums.

    I’m using GXT 2.2.3 and GWT 2.0.4.