Vaadin 24 Grid列宽获取:手动调整及容器变化后如何获取实际宽度
Vaadin 24 Grid列宽保存与容器尺寸变化监听问题解决
一、获取用户手动调整后的列实际宽度
Vaadin Grid的column.getWidth()在未显式调用setWidth()时返回null,是因为服务端默认不会同步浏览器自动计算的列宽值。要拿到用户手动调整后的实际宽度,需要通过客户端API获取后同步到服务端:
- 在列调整监听器中,通过Element的
executeJs()调用客户端Grid列的getWidth()方法:
grid.addColumnResizeListener(event -> { Column<?> targetColumn = event.getColumn(); // 执行客户端JS获取当前列的实际像素宽度 targetColumn.getElement().executeJs("return this.getWidth();") .then(Integer.class, actualWidth -> { // 这里可以将actualWidth保存到会话或数据库 System.out.printf("列[%s]调整后的宽度:%dpx%n", targetColumn.getKey(), actualWidth); }); });
- 如果需要在页面加载后获取浏览器自动计算的初始宽度,可以在Grid附加到UI后执行同样的JS逻辑:
grid.addAttachListener(event -> { grid.getColumns().forEach(column -> { column.getElement().executeJs("return this.getWidth();") .then(Integer.class, initialWidth -> { // 处理初始宽度 }); }); });
二、容器尺寸变化时列宽更新的监听
addColumnResizeListener仅响应用户手动拖拽列边界的操作,容器(或窗口)尺寸变化导致的列宽自动调整不会触发该监听器。可以通过浏览器的ResizeObserverAPI监听Grid元素的尺寸变化,进而同步列宽:
- 客户端注册ResizeObserver并通知服务端:
grid.getElement().executeJs(""" const observer = new ResizeObserver(entries => { // 每次尺寸变化时调用服务端方法 $0.$server.onGridContainerResized(); }); observer.observe($0); // 可选:当Grid从DOM移除时停止监听 $0.addEventListener('detach', () => observer.disconnect()); """, grid.getElement());
- 服务端定义
@ClientCallable方法接收通知并更新列宽:
@ClientCallable public void onGridContainerResized() { // 遍历所有列获取最新宽度 for (Column<?> column : grid.getColumns()) { column.getElement().executeJs("return this.getWidth();") .then(Integer.class, newWidth -> { // 保存或应用新宽度 }); } }
额外建议
- 给每个列设置唯一的
setKey(),方便后续保存和匹配宽度; - 保存的宽度可以存在用户会话(如
VaadinSession)或数据库中,下次初始化Grid时通过setWidth(actualWidth + "px")恢复; - 如果Grid包含大量列,建议批量处理宽度获取逻辑,避免频繁的客户端-服务端通信。
内容的提问来源于stack exchange,提问作者user1119859
相关产品推荐
相关产品推荐

