Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
TreeTable alwaysRecalculateColumnWidths expand/collapse events
Hi,
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;
@Theme("valo")
public class MyUI extends UI {
@Override
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(ttable);
layout.addComponent(new Button("Resize", event -> ttable.setVisibleColumns(ttable.getVisibleColumns())));
setContent(layout);
}
@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
Thread.sleep(5);
} catch (InterruptedException ie) {
// nop
}
UI.getCurrent().access(() -> ttable.refreshRowCache());
});
thread.start();
}
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?