2016-06-13 3 views
1

Это said in documentation, чтоКак визуализировать UNLIMITED количество строк данных в TreeTableView в JavaFX?

управление табличного дерева предназначено для визуализации неограниченного количества строк данных

К сожалению, я не вижу какие-либо средств для этого в доке.

Все элементы хранятся в классах TreeItem<> и хранятся в памяти. Хотя, можно реализовать «unlimitness» с ObservableList<>. Я не вижу возможности реализовать это на вложенных наблюдаемых списках.

«Неприменимость» требует загрузки данных по требованию, а не их хранения в памяти.

Так что, наконец, можно отображать данные по запросу в TreeTableView?

+0

Возможный дубликат [JavaFX плохой дизайн: идентичность строк в наблюдаемых списках позади 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

Пожалуйста, прочтите javadoc TreeItem. Существует целый раздел о внедрении загрузки по требованию узлов, предоставляя браузер файловой системы в качестве примера (который может быть не бесконечным, но вы, конечно же, хотите загружать только нужные вещи, а не вынимать всю файловую систему в память). –

ответ

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 в какой-то (неизвестный) момент (2) ваша структура «фрактальная», то есть повторяется с уровня на уровень, но если у нас есть определенная структура в любом месте, мы можем столкнуться с трудностями. Было бы лучше иметь систему адресации и структуру данных, возвращая элемент в ответ на адрес. Как это сделано в Swing. – Dims

+0

(1) не видел этого, но я могу поиграть с ним еще немного позже. (2) не уверен, что вижу различие. В моем примере дочерние узлы вычисляются как функция «текущего» TreeItem и его значения. Вычисление здесь тривиально, но можно так же легко поговорить с сервисом и т. Д. –

Смежные вопросы