Vaadin 24 TwinColSelect如何添加选中项单独排序按钮?
为Vaadin 24 TwinColSelect添加选中项单独排序按钮的实现方案
由于Vaadin 24的TwinColSelect没有内置选中项的单个排序按钮,我们可以通过自定义组合组件的方式,将TwinColSelect与上移、下移按钮结合,实现和原Vaadin 8 ListBuilder一致的排序功能,具体实现步骤如下:
1. 创建自定义组合组件
创建一个继承自Composite的自定义组件,将TwinColSelect和排序按钮整合到布局中,同时封装排序逻辑:
import com.vaadin.flow.component.Composite; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.orderedlayout.FlexComponent; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.twincolselect.TwinColSelect; import java.util.ArrayList; import java.util.List; public class SortableTwinColSelect<T> extends Composite<VerticalLayout> { private final TwinColSelect<T> twinColSelect; private final Button moveUpBtn; private final Button moveDownBtn; public SortableTwinColSelect() { // 初始化双列选择器 twinColSelect = new TwinColSelect<>(); // 初始化排序按钮 moveUpBtn = new Button(VaadinIcon.ARROW_UP.create()); moveDownBtn = new Button(VaadinIcon.ARROW_DOWN.create()); // 初始禁用按钮 updateButtonStates(); // 绑定按钮点击事件 moveUpBtn.addClickListener(e -> moveSelectedItemUp()); moveDownBtn.addClickListener(e -> moveSelectedItemDown()); // 监听选中项变化,更新按钮可用状态 twinColSelect.addSelectionListener(e -> updateButtonStates()); // 布局组装:按钮垂直排列在选择器右侧 VerticalLayout buttonLayout = new VerticalLayout(moveUpBtn, moveDownBtn); buttonLayout.setAlignItems(FlexComponent.Alignment.CENTER); buttonLayout.setSpacing(true); getContent().add(twinColSelect, buttonLayout); getContent().setAlignItems(FlexComponent.Alignment.CENTER); getContent().setSpacing(true); } // 上移选中项逻辑 private void moveSelectedItemUp() { List<T> selectedItems = new ArrayList<>(twinColSelect.getValue()); T selectedItem = twinColSelect.getSingleSelectedItem(); if (selectedItem == null) return; int index = selectedItems.indexOf(selectedItem); if (index > 0) { // 交换当前项与前一项位置 T temp = selectedItems.get(index - 1); selectedItems.set(index - 1, selectedItem); selectedItems.set(index, temp); // 更新选中列表并保持当前项选中状态 twinColSelect.setValue(selectedItems); twinColSelect.select(selectedItem); } } // 下移选中项逻辑 private void moveSelectedItemDown() { List<T> selectedItems = new ArrayList<>(twinColSelect.getValue()); T selectedItem = twinColSelect.getSingleSelectedItem(); if (selectedItem == null) return; int index = selectedItems.indexOf(selectedItem); if (index < selectedItems.size() - 1) { // 交换当前项与后一项位置 T temp = selectedItems.get(index + 1); selectedItems.set(index + 1, selectedItem); selectedItems.set(index, temp); // 更新选中列表并保持当前项选中状态 twinColSelect.setValue(selectedItems); twinColSelect.select(selectedItem); } } // 更新按钮可用状态 private void updateButtonStates() { List<T> selectedItems = twinColSelect.getValue(); T selectedItem = twinColSelect.getSingleSelectedItem(); if (selectedItem == null || selectedItems == null || selectedItems.isEmpty()) { moveUpBtn.setEnabled(false); moveDownBtn.setEnabled(false); return; } int index = selectedItems.indexOf(selectedItem); moveUpBtn.setEnabled(index > 0); moveDownBtn.setEnabled(index < selectedItems.size() - 1); } // 暴露TwinColSelect的公共方法,方便外部配置 public TwinColSelect<T> getTwinColSelect() { return twinColSelect; } }
2. 在视图中使用自定义组件
像使用普通TwinColSelect一样配置和使用自定义组件:
// 创建可排序的双列选择器实例 SortableTwinColSelect<String> sortableSelect = new SortableTwinColSelect<>(); TwinColSelect<String> twinCol = sortableSelect.getTwinColSelect(); // 配置选择器属性 twinCol.setItems("选项1", "选项2", "选项3", "选项4", "选项5"); twinCol.setLabel("可排序的双列选择器"); twinCol.setPlaceholder("请选择选项"); twinCol.setAllItemsVisible(true); // 添加到视图 add(sortableSelect);
3. 样式优化(可选)
如果需要让按钮和选择器布局更贴合原ListBuilder的样式,可以通过CSS调整按钮尺寸、间距:
.sortable-twin-col-select button { width: 32px; height: 32px; }
然后给自定义组件添加样式类:
getContent().addClassName("sortable-twin-col-select");
内容的提问来源于stack exchange,提问作者potabattula mohan
相关产品推荐
相关产品推荐

