2017-08-02 75 views
0

我正在使用vaadin 8.1.0網格。我需要插入複選框作爲列和列標題。當我單擊列標題中的複選框時,應檢查所有列複選框。這工作正常。但問題是如果我有100行,當我檢查標題複選框時,只檢查一些列複選框,即只顯示行。當我滾動其餘行時,複選框不會被選中。這裏是我的代碼:vaadin8.1.0帶複選框的網格有問題

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); 
+0

會發生什麼,如果你也做'chk.setValue(CheckBox1.getValue())'(從已經在做它的價值變化監聽除外)在您的組件列在創建複選框後? – Morfic

+0

你嘗試過grid.setSelectionMode(SelectionMode.MULTI);而不是使用自己的複選框。 –

+0

是的,我試過SelectionMode但我的需求是不同的,我不需要選擇行。 – Apoorva

回答

0

那麼,對於性能方面的原因,不是所有的複選框從一開始就呈現時,您將在下面看到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

+0

謝謝你爲我工作。 – Apoorva

+0

@Apoorva不客氣。我希望你也看到並考慮了聽衆積累的一點點,以及你如何取消他們的註冊。 – Morfic

0

你可以人因此可以通過布爾字段「selected」擴展數據模型,或者將其包裝到一個新類中,然後添加「selected」字段。然後在添加到CheckBox的ValueChangeListener中設置/取消設置該字段。

這也將負責選擇所有網格條目,而不僅僅是渲染的一個。您只需在所有數據模型實例中更改「選定」。

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(); 
      }));