TreeTable alwaysRecalculateColumnWidths expand/collapse events


I’m having trouble with a tree-table, where column widths aren’t updated/autosized when expanding/collapsing the tree.

I’m currently using TreeTable#setVisibleColumns(TreeTable#getVisibleColumns()) to trigger a resize of the table’s columns, but it doesn’t work when invoked from expand/collapse listeners attached to the treetable, which makes it fairly useless.

See the code below - clicking the “Resize” button causes the column widths to be updated to fit the visible contents, however the expand/collapse listeners don’t. Anyone know why, or know of a work-around or other way of forcing a resize?

package test;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

import javax.servlet.annotation.WebServlet;

public class MyUI extends UI {

    protected void init(VaadinRequest vaadinRequest) {
        final VerticalLayout layout = new VerticalLayout();

        TreeTable ttable = new TreeTable("My TreeTable") {
                alwaysRecalculateColumnWidths = true;
        ttable.addContainerProperty("Name", String.class, null);
        ttable.addContainerProperty("Number", Integer.class, null);
        // Create the tree nodes and set the hierarchy
        ttable.addItem(new Object {"Menu", null}, 0);
        ttable.addItem(new Object {"Beverages", null}, 1);
        ttable.setParent(1, 0);
        ttable.addItem(new Object {"Foods", null}, 2);
        ttable.setParent(2, 0);
        ttable.addItem(new Object {"Coffee", 23}, 3);
        ttable.addItem(new Object {"Tea", 42}, 4);
        ttable.setParent(3, 1);
        ttable.setParent(4, 1);
        ttable.addItem(new Object {"Bread", 13}, 5);
        ttable.addItem(new Object {"Cake", 11}, 6);
        ttable.setParent(5, 2);
        ttable.setParent(6, 2);
        ttable.addExpandListener(event -> ttable.setVisibleColumns(ttable.getVisibleColumns()));
        ttable.addCollapseListener(event -> ttable.setVisibleColumns(ttable.getVisibleColumns()));

        layout.addComponent(new Button("Resize", event -> ttable.setVisibleColumns(ttable.getVisibleColumns())));


    @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
    @VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
    public static class MyUIServlet extends VaadinServlet {

I’ve worked out 2 things:

TreeTable#refreshRowCache() is probably a nicer way of forcing the column widths to be recalculated than my original way.

There is a work-around if you trigger the column width recalculation from a different thread using push, i.e. the following code works


ttable.addExpandListener(event → forceResize());

private void forceResize() {
Thread thread = new Thread(() → {
try {
// needs this to work consistently
} catch (InterruptedException ie) {
// nop
UI.getCurrent().access(() → ttable.refreshRowCache());
[/code]I think this is pretty ugly though, and seems to cause a bit of a flicker in the UI that isn’t otherwise there. There has to be a better way?