Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Issues with custom editor

    I am working with smartgwt 2.3 and gwt 2.6 and I am very new to this framework. I have some issues with a custom editor.

    The custom editor displays a textfield next to a combobox. It shall be used to enter quantities like e.g. 500 $, 100 m, 10 cm and so on. The text field is for the number and the combobox is for the unit.

    This is the rudimentary implementation of the widget:

    Code:
    package com.forflow.lab.smartgwt;
    
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    import com.smartgwt.client.types.Overflow;
    import com.smartgwt.client.widgets.form.DynamicForm;
    import com.smartgwt.client.widgets.form.fields.CanvasItem;
    import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
    import com.smartgwt.client.widgets.form.fields.TextItem;
    import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
    import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
    import com.smartgwt.client.widgets.form.fields.events.ShowValueEvent;
    import com.smartgwt.client.widgets.form.fields.events.ShowValueHandler;
    
    public class QuantityWidget extends CanvasItem implements ChangedHandler, ShowValueHandler {
    
        private static final Logger logger = Logger.getLogger("QuantityWidget");
    
        private DynamicForm form;
        private TextItem valueField;
        private ComboBoxItem unitField;
    
        public QuantityWidget() {
            setShouldSaveValue(true);
            addShowValueHandler(this);
            try {
                form = new DynamicForm();
                valueField = new TextItem();
                unitField = new ComboBoxItem();
    
                valueField.addChangedHandler(this);
                unitField.addChangedHandler(this);
    
                form.setMargin(0);
                
                setOverflow(Overflow.VISIBLE);
    
                valueField.setShowTitle(false);
                unitField.setShowTitle(false);
    
                unitField.setValueMap("m", "cm", "mm");
    
                form.setFields(valueField, unitField);
    
                setCanvas(form);
            } catch (Throwable t) {
                logger.log(Level.INFO, t.getLocalizedMessage(), t);
            }
        }
    
        @Override
        public void setValue(String value) {
            logger.log(Level.INFO, "setValue(String) was called");
            applyValue(value);
    
            super.setValue(value);
        }
    
        private void applyValue(String value) {
            String valuePart = value.substring(0, value.indexOf("|"));
            String unitPart = value.substring(value.indexOf("|") + 1);
    
            valueField.setValue(valuePart);
            unitField.setValue(unitPart);
        }
    
        @Override
        public void onChanged(ChangedEvent event) {
            logger.log(Level.INFO, "OnChanged was called");
            storeValue(valueField.getValueAsString() + "|" + unitField.getValueAsString());
        }
    
        @Override
        public void onShowValue(ShowValueEvent event) {
            logger.log(Level.INFO, "onShowValue was called");
            Object value = event.getDataValue();
    
            if (value instanceof String) {
                applyValue((String) value);
            }
        }
    
    }
    It works fine when used in a form. It does not work when used as the editor in a table.

    When used as an editor in a table:
    a) it doesn't write the value back into the table (the table is backed by a RecordList of ListGridRecord). I thought that "storeValue()" would be the method I need to call, but maybe I am missing something. What is missing?
    b) the widget will not fit snuggly into the cell of the table. I would either like the table cell to get larger (like e.g. the slider editor in one of the showcase examples), or implement the widget so that it squeezes itself into the space available for the table cell. Not sure how to do either of those.

    I have been trying different implementations yesterday. I am aware that sometimes instance variables should not be used in canvas item subclasses that are used as editor. I did set an editor customizer which always creates a new QuantityWidget to circumvent this.

    I also did have an implementation that was closer to the examples given in the showcase (i.e. one with setInitHandler and then the init handler will use get/set Attribute and not access the instance variables). However, I couldn't get this approach to work. I had several iterations and several issues with this approach, but they all failed because I couldn't put and/or retrieve FormItem objects via get/setAttribute. And at some point I was not able to cast the FormItem passed into the InitHandler into a CanvasItem. So honestly, I got quite confused. It may that I am missing something very obvious.
Working...
X