2016-06-13 8 views
1

それは私がDOCにこのためにあらゆる手段を見ることができない、JavaFXのTreeTableViewで無制限の数のデータ行を視覚化する方法は?

TreeTableView制御が

残念ながらデータの 行の数に制限を可視化するために設計されていること、said in documentationです。

すべての要素は、TreeItem<>10クラスに格納され、メモリに格納されます。 ObservableList<>で "unlimitness"を実装することはできますが、これをネストされた観測可能リストに実装する方法はありません。

「Unlimitness」では、データをメモリに格納せずに要求ごとにロードする必要があります。

TreeTableViewでオンデマンドでデータを表示できるようになりましたか?

+0

可能な重複[JavaFXの悪いデザイン:?テーブルビューの背後に観察可能なリストの行のアイデンティティ](http://stackoverflow.com/questions/36937118/javafx-bad-design-row-identity-in-observable -lists-behind-the-tableview) – Itai

+0

上記のリンクされた質問は 'TableView'を参照していますが、それは同じ問題です。 James_Dの答えは(必要な変更を加えて) 'TreeTableView'にも適用できると思います。 – Itai

+2

TreeItemのjavadocをお読みください。ノードのオンデマンドローディングの実装については、ファイルシステムブラウザを例にして説明します(無限ではないかもしれませんが、ファイルシステム全体をメモリに取り込むのではなく、必要なものだけをロードしたいと思っています)。 –

答えて

1

コメントで指摘したように、documentation for TreeItemには、ツリー項目の子ノードを遅延挿入する例があります。

ここでは、非常に単純な無限ツリーテーブルの完全な例を示します。この例では、ツリー項目が折りたたまれているときに子ノードが削除され、ガベージコレクションされます。

import java.math.BigInteger; 
import java.util.function.Function; 

import javafx.application.Application; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.TreeItem; 
import javafx.scene.control.TreeTableColumn; 
import javafx.scene.control.TreeTableView; 
import javafx.stage.Stage; 

public class UnlimitedTreeTableView extends Application { 


    @Override 
    public void start(Stage primaryStage) { 
     TreeTableView<Item> treeTable = new TreeTableView<>(); 
     treeTable.setRoot(createTreeItem(BigInteger.ZERO)); 

     treeTable.getColumns().add(column("Item", Item::getName)); 
     treeTable.getColumns().add(column("Value", Item::getValue)); 

     primaryStage.setScene(new Scene(treeTable)); 
     primaryStage.show(); 
    } 

    private TreeItem<Item> createTreeItem(BigInteger value) { 
     TreeItem<Item> item = new TreeItem<Item>(new Item(String.format("Item %,d", value), value)) { 

      private boolean childrenComputed = false ; 

      { 
       expandedProperty().addListener((obs, wasExpanded, isNowExpanded) -> { 
        if (! isNowExpanded) { // remove child nodes... 
         super.getChildren().clear(); 
         childrenComputed = false ; 
        } 
       }); 
      } 

      @Override 
      public ObservableList<TreeItem<Item>> getChildren() { 
       if (! childrenComputed) { 
        Item item = getValue(); 
        BigInteger value = item.getValue() ; 
        BigInteger valueTimes10 = value.multiply(BigInteger.TEN); 
        for (int i = 0 ; i < 10 ; i++) { 
         BigInteger v = BigInteger.valueOf(i); 
         super.getChildren().add(createTreeItem(valueTimes10.add(v))); 
        } 
        childrenComputed = true ; 
       } 
       return super.getChildren(); 
      } 

      @Override 
      public boolean isLeaf() { 
       return false ; 
      } 
     }; 

     return item ; 
    } 

    private static <S,T> TreeTableColumn<S,T> column(String title, Function<S,T> property) { 
     TreeTableColumn<S,T> column = new TreeTableColumn<>(title); 
     column.setCellValueFactory(cellData -> 
      new SimpleObjectProperty<T>(property.apply(cellData.getValue().getValue()))); 
     column.setPrefWidth(200); 
     return column ; 
    } 

    public static class Item { 
     private final BigInteger value ; 
     private final String name ; 

     public Item(String name, BigInteger value) { 
      this.name = name ; 
      this.value = value ; 
     } 

     public BigInteger getValue() { 
      return value; 
     } 

     public String getName() { 
      return name; 
     } 


    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

(1)構造が「フラクタル」、すなわちレベルごとに繰り返されている(未知の)瞬間(2)でスタックオーバーフローが発生しましたが、どこにでも特定の構造があれば、困難に直面する可能性があります。アドレッシングシステムとデータ構造を持ち、アドレスに応答してアイテムを返す方がよいでしょう。それはスイングで作った。 – Dims

+0

(1)はそれが起こるのを見たことがありませんでしたが、私はもう少し後でそれをすることができます。 (2)区別がわからない。私の例では、子ノードは "現在の" TreeItemとその値の関数として計算されます。ここでの計算は簡単ですが、サービスなどと簡単にやりとりすることもできます –

関連する問題