Problem creating an "Editor Row" in a List - Getting empty Fields

We are currently trying to optimize our sluggish UI, and the main culprit seems to be our editable Lists.
Currently we are just setting the entire list to editable, and that gives us really poor performance, especially in IE.
Ref separate posting:
https://vaadin.com/forum#!/thread/8185675/8185674

Now I am trying to let just the currently selected row being editable.
I’m trying to adopt this example:
https://gist.github.com/canthony/6669418
.
When I copy this example directly, it more or less works, but when I adapt it to my own example I get empty ediable fields.

My code calls refreshRowCache() to force all the rows to be updated. AFAIK there is no way to update just a single row?
The example I’m following called setEditable(true) instead, but that method just sets editable=true and calls refreshRowCache(). Just to be sure I have tried it with setEditable(true) as well, but got the same result.

Here is my test application. It is the “List with editor-row” that is the problem:

package com.example.test_list;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.data.Container;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

@SuppressWarnings("serial")
@Theme("valo")
public class Test_listUI extends UI {

    @WebServlet(value = "/*", asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = Test_listUI.class)
    public static class Servlet extends VaadinServlet {
    }

    public static class Row {
        String[] data = new String[20]
;
        
        public Row(int rowNo) {
            for(int col=0; col<data.length; col++) {
                data[col]
 = "Row " + rowNo + ", col " + col;
            }
        }

        public String get0() { return data[0]
; }
        public String get1() { return data[1]
; }
        public String get2() { return data[2]
; }
        public String get3() { return data[3]
; }
        public String get4() { return data[4]
; }
        public String get5() { return data[5]
; }
        public String get6() { return data[6]
; }
        public String get7() { return data[7]
; }
        public String get8() { return data[8]
; }
        public String get9() { return data[9]
; }
        public String get10() { return data[10]
; }
        public String get11() { return data[11]
; }
        public String get12() { return data[12]
; }
        public String get13() { return data[13]
; }
        public String get14() { return data[14]
; }
        public String get15() { return data[15]
; }
        public String get16() { return data[16]
; }
        public String get17() { return data[17]
; }
        public String get18() { return data[18]
; }
        public String get19() { return data[19]
; }

        public void set0(String val) { data[0]
 = val; }
        public void set1(String val) { data[1]
 = val; }
        public void set2(String val) { data[2]
 = val; }
        public void set3(String val) { data[3]
 = val; }
        public void set4(String val) { data[4]
 = val; }
        public void set5(String val) { data[5]
 = val; }
        public void set6(String val) { data[6]
 = val; }
        public void set7(String val) { data[7]
 = val; }
        public void set8(String val) { data[8]
 = val; }
        public void set9(String val) { data[9]
 = val; }
        public void set10(String val) { data[10]
 = val; }
        public void set11(String val) { data[11]
 = val; }
        public void set12(String val) { data[12]
 = val; }
        public void set13(String val) { data[13]
 = val; }
        public void set14(String val) { data[14]
 = val; }
        public void set15(String val) { data[15]
 = val; }
        public void set16(String val) { data[16]
 = val; }
        public void set17(String val) { data[17]
 = val; }
        public void set18(String val) { data[18]
 = val; }
        public void set19(String val) { data[19]
 = val; }

    }
    
    BeanItemContainer<Row> container;
    Component component;
    
    @Override
    protected void init(VaadinRequest request) {
        final VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);
        setContent(layout);

        HorizontalLayout buttons = new HorizontalLayout();
        layout.addComponent(buttons);
        
        container = new BeanItemContainer<>(Row.class);

        for(int i=1; i<100; i++) {
            container.addBean( new Row(i));
        }
        
        Button button = new Button("Plain list");
        button.addClickListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {

                if(component!=null) {
                    layout.removeComponent(component);
                }

                Table table = new Table("Plain list", container);
                table.setSelectable(true);
                table.setNullSelectionAllowed(false);
                component = table;
                layout.addComponent(component);
            }
        });
        buttons.addComponent(button);

        button = new Button("Editable list");
        button.addClickListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                
                if(component!=null) {
                    layout.removeComponent(component);
                }
                
                final Table table = new Table("Editable list", container);
                table.setSelectable(true);
                table.setNullSelectionAllowed(false);
                table.setEditable(true);
                component = table;
                layout.addComponent(component);
            }
        });
        buttons.addComponent(button);

        button = new Button("List with editor-row");
        button.addClickListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                
                if(component!=null) {
                    layout.removeComponent(component);
                }
                
                final Table table = new Table("List with editor-row", container);
                table.setEditable(true);
                table.setNullSelectionAllowed(false);
                table.setTableFieldFactory(new DefaultFieldFactory() {
                    @Override
                    public Field<?> createField(Container container, Object itemId, Object propertyId, Component uiContext) {
                        // If the itemId isn't the currently selected item in the table, don't generate a field
                        // i.e. it's not editable
                        if (!itemId.equals(table.getValue())) {
                            return null;
                        }
                        else {
                            return super.createField(container, itemId, propertyId, uiContext);
                        }
                    }
                });

                table.addValueChangeListener(new ValueChangeListener() {

                    @Override
                    public void valueChange(ValueChangeEvent event) {
                        table.refreshRowCache();
                    }
                
                });
                
                table.setSelectable(true);
                
                component = table;
                layout.addComponent(component);
            }
        });
        buttons.addComponent(button);

        button = new Button("HTML table");
        button.addClickListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                
                if(component!=null) {
                    layout.removeComponent(component);
                }
                
                StringBuilder sb = new StringBuilder();
                sb.append("<table>\n");
                
                for(Object itemId : container.getItemIds()) {
                    sb.append("<tr>");
                    
                    BeanItem<Row> beanItem = container.getItem(itemId);
                    
                    for(Object propertyId : beanItem.getItemPropertyIds()) {
                        sb.append("<td>").append(beanItem.getItemProperty(propertyId).getValue()).append("</td>");
                    }
                    
                    sb.append("</tr>\n");
                }
                
                sb.append("</table>\n");
                
                Label label = new Label(sb.toString());
                label.setContentMode(ContentMode.HTML);
                component = label;
                layout.addComponent(component);
            }
        });
        buttons.addComponent(button);
    
    }

}

Anyone?

Well, further debug indicates that this problem only happens when I call refreshRowCache() as part of the valueChanged event handler. If I add a button outside the list and calls refreshRowCache() or toggle editMode, nothing bad happens.

I thought perhaps the caller did some more work after calling my valueChanged, so I tried to move the call to some later point.
I tried to override Table.setValue and call refreshRowCache() after I had called super, and I even tried to override Table.beforeClientResponse and call it there, but I got the same error.

So, I assume that it is the client-side that gets confused.

Not sure what else I can do here, so I’ve created a ticket:
http://dev.vaadin.com/ticket/14684

I found a way forwards for my editor-row.

I’ve now set the list to non-selectable and removed the valueChangeListener .
Instead I’ve added an itemClickListener where I 1st set the list value, and then call refreshRowCache()

With this in place, the list is re-rendered and the “editor row” shows up with editable Fields that shows the values as expected.

I’ve now also gotten a workaround suggested on the ticket i submitted:
http://dev.vaadin.com/ticket/14684

I prefer this workaround to my own, since I now can let Vaadin handle row selection as before, and don’t have to re-implement multi-row selection from my own itemClicked event handler.