代码之家  ›  专栏  ›  技术社区  ›  Apoorva

带有复选框的Vaadi8.1.0网格出现问题

  •  1
  • Apoorva  · 技术社区  · 7 年前

    我正在使用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 回复  |  直到 7 年前
        1
  •  0
  •   Morfic    7 年前

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

    结果:

    rendering-of-the-checkboxes

    grid.addComponentColumn 每次都会被调用,值更改侦听器将被添加到列表中,因为它们从未被注销。看看下面的图片,在几次滚动之后,我最终得到了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

        2
  •  0
  •   Mihael    7 年前

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

        3
  •  0
  •   Mihael    7 年前

    另一种方法是使用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();
                }));