Framework: Grid frozen columns state updating

Created on 23 Feb 2018  路  8Comments  路  Source: vaadin/framework

  • Vaadin Framework version (e.g. 8.3.1)
  • Chrome
  • Description:
    Grid doesn't update frozen columns after removing columns and setting
    the same 'frozenColumnCount'

  • Minimal reproducible example:

    Grid<Person> grid = new Grid<>(Person.class);
    
    addGridColumns();
    grid.setFrozenColumnCount(3);   // all is working, Grid displays frozen columns
    
    // attach Grid
    
    grid.removeAllColumns();
    addGridColumns();
    grid.setFrozenColumnCount(3);   // Grid doesn't show frozen columns
    
    // after this, 'grid.getFrozenColumnCount()' still returns '3';
    // grid state also still keeps '3' as 'frozenColumnCount', but there is no result...
    // NOTE: setting the different 'frozenColumnCount' value updates the Grid
    

Most helpful comment

Hi!
After upgrading to V8.6.3, now I get an exception while trying to set the frozen column count.
The exception happens in the 'Grid' class in method 'setFrozenColumnCount' at line;
ui.getConnectorTracker().getDiffState(this).remove("frozenColumnCount");

The problem is in my case, ui.getConnectorTracker().getDiffState(this) is null.
I would appreciate your feedback.
In my case, my grid is always multi selectable; grid.setSelectionMode(Grid.SelectionMode.MULTI);

Update: I figured out how to tackle this. I always have to check the row count before calling the setFrozenColumnCount method. This solution even worked on V8.5.

All 8 comments

Is there any update?

Is there any update?
PS: is reproducible with 8.4.1 and 8.4.2

Hi Andrei,

it seems I hit the same problem. See Vaadin Forum: https://vaadin.com/forum/thread/17146104/17156864

As I can see this problem is known for months now. Would be nice too see this fixed in the nearer future.

Best wishes
Stefan

Sorry about the delay, I have been dealing with other projects.

I found the cause for the issue. This happens because all the changes in the Grid's state happen in a single roundtrip. So when all the columns are removed, the frozen column value is eventually set to 0, and then the value is set back to 3 again. Since this all happens in a single round trip, the state handling interprets this as "no change has happened", and the frozen column value isn't sent to the widget.

Unfortunately the column removal and recreating is done on the widget as well, and it works in a similar fashion, dropping the widget's internal frozen column count to 0. And it never gets set back to the original value, since the state handling keeps on thinking that it hasn't changed.

I have a fix for this, but it takes a while for it to be released. As an intermediary workaround you can try doing a manual push after the removeAllColumns() call, which should get the states synced properly. Of course this comes at the cost of some additional traffic.

Hi!
After upgrading to V8.6.3, now I get an exception while trying to set the frozen column count.
The exception happens in the 'Grid' class in method 'setFrozenColumnCount' at line;
ui.getConnectorTracker().getDiffState(this).remove("frozenColumnCount");

The problem is in my case, ui.getConnectorTracker().getDiffState(this) is null.
I would appreciate your feedback.
In my case, my grid is always multi selectable; grid.setSelectionMode(Grid.SelectionMode.MULTI);

Update: I figured out how to tackle this. I always have to check the row count before calling the setFrozenColumnCount method. This solution even worked on V8.5.

@youness-teimoury

Update: I figured out how to tackle this. I always have to check the row count before calling the setFrozenColumnCount method. This solution even worked on V8.5.

can you show a code snippet for your workaround ?

@mlindfors

Here is a minimal Example to reproduce the NullPointerException.

There should be a NullPointer check for getDiffState() ?

Tested with Vaadin 8.6.3

public class MyUI extends UI {

    @Override
    protected void init(final VaadinRequest request) {

        final VerticalLayout vLayout = new VerticalLayout();
        vLayout.setSizeFull();

        final Button buttonAdd = new Button("Open Window");
        buttonAdd.addClickListener(c -> {

            final GridWindow window = new GridWindow();

            window.setFrozenColumnsInGrid(1); // no crash here

            UI.getCurrent().addWindow(window);

            window.setFrozenColumnsInGrid(2); // crash after attaching to UI and setting new count
        });
        vLayout.addComponent(buttonAdd);

        setContent(vLayout);

    }

    /******************************************************************************************************************/

    public static class GridWindow extends Window {

        private final Grid<Object> grid = new Grid<>();

        public GridWindow() {

            setCaption("Need caption to show close buttons");
            setWidth("800px");
            setHeight("600px");
            center();
            setClosable(true);
            setModal(true);

            setContent(createContent());
        }

        private Component createContent() {

            this.grid.setSizeFull();

            this.grid.addColumn(item -> "col 1 data").setCaption("col_1").setWidth(100);

            this.grid.addColumn(item -> "col 2 data").setCaption("col_2").setWidth(512);
            this.grid.addColumn(item -> "col 3 data").setCaption("col_3").setWidth(512);

            return this.grid;
        }

        /**
         * will throw NullPointerException when called after attaching window to the UI
         */
        private void setFrozenColumnsInGrid(final int count) {
            this.grid.setFrozenColumnCount(count);
        }
    }
}

@d2k2-git

Wonderful, thank you. Yes, apparently if you manage to get more than one setFrozenColumnCount calls in the first server roundtrip after the component has been attached you hit this issue. And also yes, all it basically would need to fix it is a null check for the diffState before trying to remove anything from it. This has been an oversight from me, and I am sorry for the inconvenience it has caused.

Was this page helpful?
0 / 5 - 0 ratings