限制 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()
,否则更改不会传播到客户端。
在我们的一个应用程序中,我们使用惰性查询容器来浏览可能非常大的数据集。这很好用。但是,当使用多 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()
,否则更改不会传播到客户端。