Vaadin 14 两个Grid表格之间拖拽功能实现的相关问题咨询
Vaadin Grid 跨组件拖拽实现方案
核心概念解释
dragItems就是拖拽操作触发时,你选中的Grid行对应的绑定对象列表,可直接通过拖拽事件的getDraggedItems()方法获取,和你的Grid绑定的实体类泛型一致。
可直接运行的最小实现代码
你可以参考以下完整逻辑替换官方示例的省略部分,解决报错问题:
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.router.Route; import java.util.ArrayList; import java.util.List; import java.util.Optional; // 自定义绑定的实体类 class SampleItem { private String name; private int id; public SampleItem(int id, String name) { this.id = id; this.name = name; } // 必须配置getter、setter,否则Grid无法自动渲染列 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } } @Route("grid-drag-demo") public class GridDragDemoView extends HorizontalLayout { // 定义可修改的数据源列表,官方示例省略了这部分 private final List<SampleItem> sourceList = new ArrayList<>(); private final List<SampleItem> targetList = new ArrayList<>(); public GridDragDemoView() { setSizeFull(); // 初始化测试数据 for (int i = 1; i <= 5; i++) { sourceList.add(new SampleItem(i, "源条目" + i)); targetList.add(new SampleItem(i+10, "目标条目" + i)); } // 1. 配置源Grid:开启拖拽能力 Grid<SampleItem> sourceGrid = new Grid<>(SampleItem.class); sourceGrid.setItems(sourceList); sourceGrid.setRowsDraggable(true); sourceGrid.setHeightFull(); // 2. 配置目标Grid:开启放置能力 Grid<SampleItem> targetGrid = new Grid<>(SampleItem.class); targetGrid.setItems(targetList); targetGrid.setDropMode(Grid.DropMode.BETWEEN); // 允许放置在两行之间 targetGrid.setHeightFull(); // 3. 处理放置逻辑,实现索引计算 targetGrid.addDropListener(e -> { // 获取拖拽的条目(就是你问的dragItems) List<SampleItem> dragItems = e.getDraggedItems(); // 计算放置位置索引 int insertIndex; Optional<SampleItem> targetItem = e.getDropTargetItem(); if (targetItem.isEmpty()) { // 拖拽到Grid空白区域,默认放到列表末尾 insertIndex = targetList.size(); } else { // 拿到目标行的索引 insertIndex = targetList.indexOf(targetItem.get()); // 如果是放在目标行的下方,索引加1 if (e.getDropLocation() == Grid.DropLocation.AFTER) { insertIndex++; } } // 同步两个列表的数据 sourceList.removeAll(dragItems); targetList.addAll(insertIndex, dragItems); // 刷新Grid显示 sourceGrid.getDataProvider().refreshAll(); targetGrid.getDataProvider().refreshAll(); }); add(sourceGrid, targetGrid); } }
常见报错解决
- 官方示例省略了数据源初始化逻辑,直接用不可变集合作为Grid数据源会抛出修改异常,必须用
ArrayList这类可修改的集合。 - 实体类没有写getter/setter会导致Grid无法渲染列,出现空白或者报错。
- Grid没有设置明确高度会导致拖拽事件不触发,建议用
setHeightFull()或者指定固定像素高度。
内容的提问来源于stack exchange,提问作者Stimpson Cat
相关产品推荐
相关产品推荐

