vaadin8.1.0带Checkbox的网格有一个问题

时间:2017-08-02 07:49:49

标签: java maven vaadin vaadin8

我正在使用vaadin 8.1.0网格。我需要插入复选框作为列,也作为列标题。当我单击列标题中的复选框时,应选中所有列复选框。这工作正常。但问题是如果我有100行,当我检查标题复选框时,只检查一些列复选框,即只显示的行。当我向下滚动剩余的行时,不会选中复选框。这是我的代码:

    List<Person> people = new ArrayList();
         for (int i = 0; i < 1000; i++) {
          people.add(i, new Person("Galileo Galilei", 1564));
        }

    CheckBox CheckBox1 = new CheckBox("All");
    CheckBox1.setValue(false);

        Grid<Person> grid = new Grid<>();
        grid.setItems( people);
        grid.addColumn(Person::getName).setCaption("Name");
        grid.addColumn(Person::getYear).setCaption("Year of birth").setId("1");

        grid.addComponentColumn(Person -> {
            CheckBox chk=new CheckBox("Chk 2");
            CheckBox1.addValueChangeListener(e->
            chk.setValue(CheckBox1.getValue())
            );
            return chk; 
        }).setCaption("ch2").setId("CH2");

        grid.getHeaderRow(0).getCell("CH2").setComponent( CheckBox1);

3 个答案:

答案 0 :(得分:0)

嗯,出于性能原因,并非所有复选框都从头开始呈现,因为您将在下面的GIF中看到(右侧,项目以紫色闪烁),只有当前可见的复选框。当您滚动时,新项目将替换旧项目,并将为它们绘制复选框。但是,它们的初始状态将被取消设置,因此最简单的解决方案是将其初始状态设置为 master复选框CheckBox chk = new CheckBox("Chk 2", CheckBox1.getValue());

结果:

rendering-of-the-checkboxes

此外,查看代码可能会有轻微泄漏。由于每次滚动较大的部分时都会绘制复选框,因此每次都会调用grid.addComponentColumn中的代码,并且值更改侦听器将一直添加到列表中......因为它们是&#39;永远不会注册。看看下面的图片,经过几次滚动,我最终得到了超过9000个:

value change listeners accumulating

要解决此问题,您可以在分离复选框时取消注册侦听器:

grid.addComponentColumn(Person -> {
     CheckBox chk = new CheckBox("Chk 2", CheckBox1.getValue());
     // save the registration info to unregister at a later time
     Registration listenerRegistration = CheckBox1.addValueChangeListener(e -> chk.setValue(CheckBox1.getValue()));
     // when the checkbox is detached, remove the listener
     chk.addDetachListener(event -> listenerRegistration.remove());
     return chk;
 }).setCaption("ch2").setId("CH2");

现在该列表仅包含那些尚未分离的人:

smaller-list-of-listeners

答案 1 :(得分:0)

您还可以通过布尔字段“选择”扩展数据模型,或将其包装到新类中,然后添加“选定”字段。然后设置/取消将ValueChangeListener中的字段添加到CheckBox。

这也将负责选择所有网格条目,而不仅仅是渲染的网格条目。您只需在所有数据模型实例中更改“已选择”。

答案 2 :(得分:0)

另一种方法是使用ImageRenderer。那么你就不必处理任何听众了。

这假定您的模型具有保存已选中/已选择值的属性。

ThemeResource resourceChecked = new ThemeResource("selected.gif");
ThemeResource resourceUnchecked = new ThemeResource("deselected.gif");

grid.addColumn(person -> person.getSelected() ? resourceChecked : resourceUnchecked, 
    new ImageRenderer<>(event -> { 
                Person person = event.getItem();
                person.setSelected(!person.getSelected());
                grid.getDataProvider().refreshItem(person);
                grid.markAsDirty();
            }));