2016-06-13 13 views
1

내가이 문서에서 이것에 대한 어떤 수단을 볼 수 없습니다,JavaFX의 TreeTableView에서 무제한 데이터 행을 시각화하는 방법은 무엇입니까?

TreeTableView 제어가

불행하게도 데이터의 행의 수를 무제한으로 시각화하도록 설계되어, said in documentation입니다.

모든 요소는 TreeItem<> 클래스에 저장되고 메모리에 저장됩니다. 비록 하나가 ObservableList<>으로 "unlimitness"를 구현할 수 있지만 중첩 된 관측 가능 목록에이를 구현할 방법이 없습니다.

"Unlimitness"는 필요에 따라 데이터를로드하고 메모리에 저장하지 말아야합니다.

TreeTableView에서 주문형 데이터를 표시 할 수 있습니까?

+0

가능한 복제 [자바 FX 나쁜 디자인 :?를있는 TableView 뒤에 관찰 목록에있는 행의 정체성 (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을 읽으십시오. 파일 시스템 브라우저를 예로 들면, 노드의 주문형로드 (on-demand loading) 구현에 대한 전체 섹션이 있습니다 (무한하지 않을 수도 있지만, 전체 파일 시스템을 메모리로 끌어 오지 않고 필요한 것만로드하려고합니다). –

답변

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) 구조가 "프랙탈"즉 레벨에서 레벨로 반복되는 일부 (알 수없는) 순간에 stackoverflow가 발생하지만, 특정 위치에 구조가 있으면 어려움을 겪을 수 있습니다. 주소 시스템 및 데이터 구조를 가지고 주소에 응답하여 항목을 반환하는 것이 좋습니다. 그것이 스윙에서했던 것처럼. – Dims

+0

(1) 그 일은 보지 못했지만 나중에 좀 더 놀 수 있습니다. (2) 나는 구별을 알지 못한다. 내 예제에서 자식 노드는 "현재"TreeItem과 그 값의 함수로 계산됩니다. 계산은 간단하지만 서비스와 쉽게 대화 할 수 있습니다. –