限制 Vaadin 中选定行的数量 Table

Limiting number of selected rows in Vaadin Table

在我们的一个应用程序中,我们使用惰性查询容器来浏览可能非常大的数据集。这很好用。但是,当使用多 select table 时,可以 select 任意数量的行。 在我们的例子中,这可能导致 select 最多 500.000 行(Vaadin 限制)然后使 VM 崩溃。

有没有办法限制 selected 行数?

这是一个显示问题的示例:

public class UIImpl extends UI {
    private int SIZE = 500000;

    @Override
    protected void init(VaadinRequest request) {

        // add a large table
        LazyQueryContainer lqc = new LazyQueryContainer(
            new QueryFactory() {
                public Query constructQuery(QueryDefinition qd) {
                    return new Query() {
                        @Override
                        public int size() {
                            return SIZE;
                        }

                        @Override
                        public void saveItems(List<Item> addedItems, List<Item> modifiedItems, List<Item> removedItems) {   }

                        @Override
                        public List<Item> loadItems(int startIndex, int  count) {
                            List<Item> r = new ArrayList<>(count);
                            for (int i = startIndex; i<startIndex+count;i++) {
                                PropertysetItem item = new PropertysetItem();
                                item.addItemProperty("name", new ObjectProperty(i));
                                r.add(item);
                            }
                            return r;
                        }

                        @Override
                        public boolean deleteAllItems() {
                            return false;
                        }

                        @Override
                        public Item constructItem() {
                            return null;
                        }
                    };
                }
            },
            null,
            20,
            false
        );

        lqc.addContainerProperty("name", Integer.class, null);

        Table table = new Table();
        table.setContainerDataSource(lqc);
        table.setMultiSelect(true);
        table.setSelectable(true);
        table.setImmediate(true);
        table.setVisibleColumns("name");
        table.setSizeFull();
        table.addValueChangeListener(new Property.ValueChangeListener() {
            public void valueChange(Property.ValueChangeEvent event) {
                System.err.println(event.getProperty().getValue());
            }
        });
        setContent(table);
    }
}

如果您想限制用户能够访问的行数 select 您可以使用类似于以下代码的内容:

public class TableWithSelectionLimit extends Table {

    private final int maxSelections= -1;
    private String[] lastSelected;

    public TableWithSelectionLimit(int maxSelections) {
      this.maxSelections = maxSelections;
    }

    @Override
    public void changeVariables(Object source, Map<String, Object> variables) {
      String[] selected = (String[]) variables.get("selected");
      if (selected != null && selected.length > maxSelections) {
        if (lastSelected != null) {
          variables.put("selected", lastSelected);
        } else {
          variables.remove("selected");
        }

        markAsDirty();
      } else {
        lastSelected = selected;
      }

      super.changeVariables(source, variables);
    }
}

这当然是可以优化的,但它会让您了解如何做到这一点。


更新

为了处理使用 "Shift"+Click 产生的 select 离子,还必须在上述方法中 handle/update 这些 select 离子范围。

可以使用 variables.get("selectedRanges") 检索这些内容,这将 return 一个 String[] 包含 "8-10" 之类的项目,而

  • 第一个数字是:select离子范围的起始索引
  • 第二个数字 是:从该索引
  • 开始selected 的项目数量

使用此信息应该可以根据需要更新这些值并使用 variables.put("selectedRanges", updatedRanges).

将它们放回变量中

注意:如果值发生变化,请不要忘记调用markAsDirty(),否则更改不会传播到客户端。