2017-08-02 8 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

はどうなりますか? – 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のコードが毎回呼び出され、値変更リスナーがリストに追加されます。登録されないためです。これを克服するために

value change listeners accumulating

、あなたはチェックボックスが取り外されたリスナーの登録を解除することができます:少数スクロールした後、私は彼らの9000以上になってしまった、下の画像を見てみましょう

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

あなたは可能性がアルデータモデルをブールフィールド「選択済み」で拡張するか、新しいクラスにラップし、そこに「選択済み」フィールドを追加します。次に、CheckBoxに追加されたValueChangeListenerでそのフィールドを設定/設定解除します。

これは、レンダリングされたものだけでなく、すべてのグリッド・エントリの選択にも役立ちます。すべてのデータモデルインスタンスで「選択済み」を変更するだけで済みます。

0

もう1つの方法は、ImageRendererを使用することです。その後、リスナーに対処する必要はありません。

これは、モデルにチェック/選択された値を保持する属性があることを前提としています。あなたも `chk.setValue(CheckBox1.getValue())`コンポーネント列のチェックボックスを作成した後(脇すでに値変更リスナーにそれをやってから)行う場合

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(); 
      })); 
関連する問題