After migrating from GXT 2.2.5 to 2.3.1a I've got a problem with RowEditors and ComboBoxes.

When I'm using a ComboBox that doesn't allow empty values and I'm clicking 'Save' in the RowEditor the results will not be saved. After debugging I noticed in the RowEditor#stopEditing method, that ComboBoxes will be cleared (line 503) and I think because of this, the following isValid-check for the RowEditor returns false (ComboBox is empty -> not allowed) and editing is canceled.

Is there a special reason why the ComboBoxes will be cleared? In 2.2.5 I can't find this and everything there is working great.


Thanks for your help!


EDIT:
In release notes for 2.3.1 I found this bug-fix. I think I could be related to this problem:
  • [EXTGWT-3233] - RowEditor Grid - Blank combo value after first edit
EDIT2:
Here is an example with EntryPoint. Compile and open it, than change a row and click save - nothing will be saved.
If you replace the RowEditor with the FixedRowEditor everything works fine. The FixedRowEditor uses the same stopEditing-method than the RowEditor - except the ComboBox#clear() call. So this call should be the problem.

Code:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.RootPanel;


import com.extjs.gxt.ui.client.core.FastMap;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.RowEditorEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Record;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.LabelField;
import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.RowEditor;


public class RowEditorBug implements EntryPoint {
    @Override
    public void onModuleLoad() {
        List<ColumnConfig> columns = new ArrayList<ColumnConfig>();


        final SimpleComboBox<String> combo = new SimpleComboBox<String>();
        combo.setForceSelection(true);
        combo.setTriggerAction(TriggerAction.ALL);
        combo.setAllowBlank(false);
        combo.add("Yes");
        combo.add("No");


        CellEditor editor = new CellEditor(combo) {
            @Override
            public Object preProcessValue(Object value) {
                if (value == null) {
                    return value;
                }
                return combo.findModel(value.toString());
            }


            @Override
            public Object postProcessValue(Object value) {
                if (value == null) {
                    return value;
                }
                return ((ModelData) value).get("value");
            }
        };


        ColumnConfig column = new ColumnConfig();
        column.setId("yesno");
        column.setHeaderHtml("Yes/No");
        column.setWidth(130);
        column.setEditor(editor);
        columns.add(column);


        TextField<String> text = new TextField<String>();
        text.setAllowBlank(false);


        column = new ColumnConfig();
        column.setId("name");
        column.setHeaderHtml("Name");
        column.setWidth(200);
        column.setEditor(new CellEditor(text));
        columns.add(column);


        ColumnModel cm = new ColumnModel(columns);


        ListStore<BaseModel> store = new ListStore<BaseModel>();
        store.add(createModelData("Yes", "Adam"));
        store.add(createModelData("No", "Sam"));
        store.add(createModelData("No", "Victoria"));


        Grid<BaseModel> grid = new Grid<BaseModel>(store, cm);
        grid.setHeight(200);
        grid.addPlugin(new RowEditor<BaseModel>());


        Viewport vp = new Viewport();
        vp.add(grid);


        RootPanel.get().add(vp);
    }


    private BaseModel createModelData(String yesno, String name) {
        BaseModel md = new BaseModel();
        md.set("yesno", yesno);
        md.set("name", name);


        return md;
    }


    private class FixedRowEditor<M extends ModelData> extends RowEditor<M> {
        public native void setEditing(boolean editing) /*-{
            this.@com.extjs.gxt.ui.client.widget.grid.RowEditor::editing = editing;
        }-*/;


        public native Record getRecord() /*-{
            return this.@com.extjs.gxt.ui.client.widget.grid.RowEditor::record;
        }-*/;


        public void stopEditing(boolean saveChanges) {
            if (disabled || !isEditing()) {
                return;
            }
            setEditing(false);// editing = false;


            Map<String, Object> data = new FastMap<Object>();
            boolean hasChange = false;
            ColumnModel cm = grid.getColumnModel();
            for (int i = 0, len = cm.getColumnCount(); i < len; i++) {
                if (!cm.isHidden(i)) {
                    Component c = getItem(i);
                    if (c instanceof LabelField) {
                        continue;
                    } else if (c instanceof Field<?>) {
                        Field<?> f = (Field<?>) c;


                        // store may be filtered from previous edit
                        if (f instanceof ComboBox<?>) {
                            ((ComboBox<?>) f).getStore().clearFilters();
                        }


                        String dindex = cm.getDataIndex(i);
                        Object oldValue = getRecord().get(dindex);


                        CellEditor ed = cm.getEditor(i);
                        Object value = ed != null ? ed.postProcessValue(f.getValue()) : f.getValue();
                        if ((oldValue == null && value != null) || (oldValue != null && !oldValue.equals(value))) {
                            data.put(dindex, value);
                            hasChange = true;
                        }
                    }


                    // In original RowEditor the ComboBox will be cleared here
                    // Don't know why.. it's causing troubles -> removed
                }
            }
            RowEditorEvent ree = new RowEditorEvent(this, rowIndex);
            ree.setRecord(getRecord());
            ree.setChanges(data);


            if (!saveChanges || !isValid()) {
                fireEvent(Events.CancelEdit, ree);
            } else if (hasChange && fireEvent(Events.ValidateEdit, ree)) {
                getRecord().beginEdit();
                for (String k : data.keySet()) {
                    getRecord().set(k, data.get(k));
                }
                getRecord().endEdit();
                fireEvent(Events.AfterEdit, ree);
            }
            hide();
        }
    }
}