2016-06-13 7 views
1

Il est said in documentation, queComment visualiser le nombre illimité de lignes de données dans TreeTableView dans JavaFX?

contrôle TreeTableView est conçu pour visualiser un nombre illimité de lignes de données

Malheureusement, je ne vois aucun moyen pour cela dans le doc.

Tous les éléments sont stockés dans TreeItem<> classes et stockés en mémoire. Bien que, on puisse implémenter "unlimitness" avec ObservableList<> je ne vois aucun moyen de l'implémenter sur des listes observables imbriquées. "Unlimitness" nécessite le chargement de données à la demande, et ne les stocke pas en mémoire.

Est-il finalement possible d'afficher des données à la demande dans TreeTableView?

+0

double possible de [JavaFX mauvaise conception: identité de ligne dans les listes observables derrière le TableView] (http://stackoverflow.com/questions/36937118/javafx-bad-design-row-identity-in-observable -lists-behind-the-tableview) – Itai

+0

La question liée ci-dessus fait référence à 'TableView', mais c'est le même problème. Je crois que la réponse de James_D pourrait également s'appliquer (avec les changements nécessaires) à 'TreeTableView'. – Itai

+2

Veuillez lire javadoc de TreeItem. Il y a une section entière sur l'implémentation du chargement des nœuds à la demande, donnant un exemple au navigateur du système de fichiers (qui peut être non infini, mais vous voulez charger uniquement les choses nécessaires, plutôt que de récupérer tout le système de fichiers en mémoire). –

Répondre

1

Comme indiqué dans les commentaires, le documentation for TreeItem a un exemple de remplir paresseusement les nœuds enfants de l'élément de l'arbre.

Voici un exemple complet très simple d'une table arborescente infinie. Dans cet exemple, les nœuds enfants sont supprimés lorsque l'élément de l'arborescence est réduit, ce qui permet de les récupérer.

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) J'ai stackoverflow à un moment (inconnu) (2) votre structure est "fractale" c'est-à-dire répétée de niveau en niveau, mais si nous avons une structure spécifique à n'importe quel endroit, nous pouvons rencontrer des difficultés. Il serait préférable d'avoir un système d'adressage et une structure de données, renvoyant l'élément en réponse à l'adresse. Comme cela a été fait à Swing. – Dims

+0

(1) ne l'a pas vu mais je peux jouer avec ça plus tard. (2) pas sûr que je vois la distinction. Dans mon exemple, les nœuds enfants sont calculés en fonction du TreeItem "actuel" et de sa valeur. Le calcul ici est trivial mais il pourrait tout aussi bien parler à un service etc. –