Grid recalculateColumnWidths doesn't recalculate on first attempt

I wrote some sample code to test resizing column widths based on a column becoming full with text and using the built-in Grid column width recalculation API.
I set up a button to update the text in one of the columns and then recalculate the column widths. Unfortunately, it doesn’t recalculate after updating the text. However, if I click the button a second time, the recalculate does work.

Here’s my sample code to demonstrate:

	public Grid2() {
		ThreeString ts1 = new ThreeString("111", "222", "333");
		ThreeString ts2 = new ThreeString("444", "555", "667");
		
		Collection<ThreeString> itemList = new ArrayList<ThreeString>();
		itemList.add(ts1);
		itemList.add(ts2);
		
		Grid<ThreeString> grid1 = new Grid<>();
		grid1.setHeightByRows(true);
		
		grid1.setItems(itemList);

		grid1.addColumn(ThreeString::getA).setHeader("First String").setSortable(true).setResizable(true)
		.setAutoWidth(true);
		grid1.addColumn(ThreeString::getB).setHeader("Second String").setSortable(true).setResizable(true)
		.setAutoWidth(true);
		grid1.addColumn(ThreeString::getC).setHeader("Third String").setSortable(true).setResizable(true)
		.setAutoWidth(true);

		add(grid1);
		
		Button button = new Button("Add Text");
		button.addClickListener(event -> {
			ts2.setB("This string became really long and it will cause the cell to grow its width and not truncate.");
			grid1.getDataProvider().refreshAll();
			grid1.recalculateColumnWidths();
		});
		
		add(button);

	}

I assume I’m calling the API to recalculate at the wrong time (i.e. in the button click listener). How should I be calling the API to recalculate the widths so that it updates when I click the button the first time?

Sounds like it could be a bug. You should file a ticket in https://github.com/vaadin/vaadin-grid-flow/issues .

Although the ticket was created and already fixed in Vaadin Grid, unfortunately Vaadin 14.1.21 doesn’t include the fix yet.

Temporary workaround:

grid.getElement().executeJs("setTimeout(() => { this.recalculateColumnWidths() }, 0)");

Herman Bovens:
Although the ticket was created and already fixed in Vaadin Grid, unfortunately Vaadin 14.1.21 doesn’t include the fix yet.

Temporary workaround:

grid.getElement().executeJs("setTimeout(() => { this.recalculateColumnWidths() }, 0)");

Do you have a link to the ticket you can share so I can track it? We are running into the same issue and would like to know when it’s available.

Here: https://github.com/vaadin/vaadin-grid-flow/issues/855

As you can see it was already closed on February 11. Not sure how to track which release of Vaadin this ends up in.

Hi, I checked and the fix for [#855]
(https://github.com/vaadin/vaadin-grid-flow/issues/855) was released in Grid [4.1.2]
(https://github.com/vaadin/vaadin-grid-flow/releases/tag/4.1.2) included in Vaadin [14.1.18]
(https://github.com/vaadin/platform/releases/tag/14.1.18)

If this issue with grid.getDataProvider().refreshAll(); grid.recalculateColumnWidths(); can still be reproduced with latest 14.1.23 then it should be reported in [vaadin-grid-flow]
(https://github.com/vaadin/vaadin-grid-flow/issues) with the code to reproduce it.

Guillermo Alvarez:
Hi, I checked and the fix for [#855]
(https://github.com/vaadin/vaadin-grid-flow/issues/855) was released in Grid [4.1.2]
(https://github.com/vaadin/vaadin-grid-flow/releases/tag/4.1.2) included in Vaadin [14.1.18]
(https://github.com/vaadin/platform/releases/tag/14.1.18)

If this issue with grid.getDataProvider().refreshAll(); grid.recalculateColumnWidths(); can still be reproduced with latest 14.1.23 then it should be reported in [vaadin-grid-flow]
(https://github.com/vaadin/vaadin-grid-flow/issues) with the code to reproduce it.

I confirmed today that the issue persists in 14.1.23.

[Issue]
(https://github.com/vaadin/vaadin-grid-flow/issues/929) created.

A rather hacky workaround involves doing the recalculation via one extra client-server round trip.

First, inside the Button click listener add:

Page page = UI.getCurrent().getPage();
page.executeJs("$0.$server.recalculateColumnWidths()",getElement());

Then add the method where the grid’s recalculation would actually occur:

@ClientCallable
public void recalculateColumnWidths() {
        grid.recalculateColumnWidths();
}