FAQ JavaFXConsultez toutes les FAQ

Nombre d'auteurs : 4, nombre de questions : 507, dernière mise à jour : 2 novembre 2016  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur le forum JavaFX de http://java.developpez.com ainsi que l'expérience personnelle des auteurs.

Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.

Sur ce, nous vous souhaitons une bonne lecture.


SommaireSceneGraphInterface utilisateurContrôlesContrôles virtualisésTreeTableView (7)
précédent sommaire suivant
 

Un TreeTableView<S> (littéralement, une vue sur un arbre-table) est un contrôle virtualisé qui fonctionne à la fois comme les contrôles TableView (la table) et TreeView (l'arbre) : il s'agit d'une table qui stocke ses données de type S non plus dans une liste, mais dans une arborescence. Graphiquement, la table affiche un arbre dans sa première colonne et il est possible de cacher ou d'afficher des lignes de la table en dépliant des branches de l'arbre.



Ainsi, la plupart des astuces de la FAQ concernant le contrôle TreeView et applicables à la manipulation des instances de la classe TreeItem peuvent directement être utilisées ici.

Mis à jour le 15 mars 2015 bouye

Pour ajouter des valeurs dans un TreeTableView, il faut les placer dans des instances de la classe javafx.scene.control.TreeItem<S> de manière à former une arborescence. La racine de cette arborescence doit être ensuite placée dans la propriété root de l'arbre-table.

Par exemple :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
final TreeItem<String> fruitItem = new TreeItem<>("Fruits"); 
fruitItem.getChildren().setAll( 
        new TreeItem("Fraise"), 
        new TreeItem("Pomme"), 
        new TreeItem("Poire") 
); 
fruitItem.setExpanded(true); 
final TreeItem<String> vegetableItem = new TreeItem<>("Légumes"); 
vegetableItem.getChildren().setAll( 
        new TreeItem("Artichaut"), 
        new TreeItem("Laitue"), 
        new TreeItem("Radis") 
); 
vegetableItem.setExpanded(true); 
final TreeItem<String> treeRoot = new TreeItem<>("Fruits & légumes"); 
treeRoot.setExpanded(true); 
treeRoot.getChildren().setAll(fruitItem, vegetableItem); 
treeTableView.setRoot(treeRoot);

Ce qui nous donne :

Mis à jour le 15 mars 2015 bouye

Initialement un TreeTableView ne contient aucune colonne. Pour ajouter des colonnes dans un arbre-table, il faut créer des objets de type javafx.scene.control.TreeTableColumn<S, T> et les ajouter dans la liste observable columns de l'arbre-table.

Ici :

  • S est le type des objets contenus dans l'instance de TreeTableView ;
  • T est le type des objets qui seront affichés ou édités dans la colonne.


Par exemple :

Code Java : Sélectionner tout
1
2
final TreeTableColumn<Car, String> modelColumn = new TreeTableColumn<>("Modèle"); 
treeTableView.getColumns().setAll(modelColumn);

Ici, nous avons ajouté dans l'arbre-table graphique une colonne nommée « Modèle » qui pour chaque objet de type Car présent dans la table affichera un objet de type String (le modèle de la voiture).

Nous pouvons également ajouter quelques colonnes supplémentaires en suivant le même principe :

Code Java : Sélectionner tout
1
2
3
4
5
final TreeTableColumn<Car, String> brandColumn = new TreeTableColumn<>("Marque"); 
final TreeTableColumn<Car, Color> colorColumn = new TreeTableColumn<>("Couleur"); 
final TreeTableColumn<Car, Integer> seatsColumn = new TreeTableColumn<>("Sièges"); 
final TreeTableColumn<Car, Integer> doorsColumn = new TreeTableColumn<>("Portes"); 
tableView.getColumns().addAll(brandColumn, colorColumn, seatsColumn, doorsColumn);

ce qui nous donne :



Pour retirer des colonnes, il suffit de les retirer la liste observable columns de l'arbre-table.

Mis à jour le 15 mars 2015 bouye

Pour faire des sous-colonnes, il suffit d'ajouter des colonnes dans la liste observable columns d'une autre colonne.

Par exemple :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
final TreeTableColumn<Car, String> modelColumn = new TreeTableColumn<>("Modèle"); 
final TreeTableColumn<Car, String> brandColumn = new TreeTableColumn<>("Marque"); 
final TreeTableColumn<Car, Color> colorColumn = new TreeTableColumn<>("Couleur"); 
final TreeTableColumn<Car, Integer> seatsColumn = new TreeTableColumn<>("Sièges"); 
final TreeTableColumn<Car, Integer> doorsColumn = new TreeTableColumn<>("Portes"); 
final TreeTableColumn<Car, ?> optionsColumn = new TreeTableColumn<>("Options"); 
optionsColumn.getColumns().setAll(colorColumn, seatsColumn, doorsColumn); 
treeTableView.getColumns().setAll(modelColumn, brandColumn, optionsColumn);

Ce qui nous donne :



Ici, les colonnes « Couleur », « Sièges » et « Portes » sont incluses dans la colonne « Options ».

Pour retirer des colonnes, il suffit de les retirer la liste observable columns de la colonne mère.

Mis à jour le 15 mars 2015 bouye

Par défaut, dans un TreeTableView, l'arbre s'affiche toujours dans la première colonne de la table. Cela reste le cas même si vous modifiez l'ordre des colonnes via l'API ou à la souris : la colonne en première position est toujours celle dans laquelle s'affiche l'arbre, quelle que soit cette colonne.

Par exemple :

Code Java : Sélectionner tout
treeTableView.getColumns().setAll(nameColumn, photoColumn, priceColumn);

Ce qui nous donne :



Ici, par défaut c'est la colonne nameColumn qui affiche l'arbre.

Si on déplace la colonne photoColumn en première position avec la souris, c'est elle qui affichera l'arbre désormais.



Il est cependant possible de spécifier la valeur de la propriété treeColumnde l'arbre-table en lui donnant une référence vers une colonne du TreeTableView. Dans ce cas, l'arbre sera affiché dans cette colonne, même si la colonne n'est pas en première position. De plus, si vous déplacez la colonne à une autre position, celle-ci continuera d'afficher l'arbre où qu'elle se trouve.

Par exemple :

Code Java : Sélectionner tout
treeTableView.setTreeColumn(priceColumn);

Ce qui nous donne :



Désormais c'est la troisième colonne, la colonne priceColumn, qui affiche l'arbre.

Si on déplace la colonne priceColumn avec la souris, elle continue à afficher l'arbre :

Mis à jour le 15 mars 2015 bouye

Tout comme les colonnes d'une TableView, les colonnes d'un TreeTableView nécessitent d'utiliser une fabrique à valeurs (value cell factory en anglais) de manière à ce qu'une colonne de type <S, T> puisse afficher, et éditer, des objets de type T à partir d'objets de type S contenus dans l'arbre-table.

Il y a deux différences dont il faut tenir compte quand on crée une fabrique à valeurs pour les colonnes d'un TreeTableView:

  • les colonnes d'un arbre-table sont de type TreeTableColumn<S, T> alors que celles d'une table sont de type TableColumn<S, T> ;
  • l'arbre-table contient des données de type TreeItem<S> tandis que la table contient directement des valeurs de type S.

Pour le reste, deux contrôles fonctionnent grosso modo de manière similaire et donc vous pouvez vous inspirer de ce qui est écrit dans la FAQ pour les TableView.

Ce qui nous donne, par exemple :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
modelColumn.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<Car, String>, ObservableValue<String>>() { 
  
    @Override 
    public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<Car, String> param) { 
        final TreeItem<Car> item = param.getValue(); 
        final Car car = item.getValue(); 
        return new SimpleStringProperty(car.getModel()); 
    } 
});

Ou :

Code Java : Sélectionner tout
1
2
3
4
5
modelColumn.setCellValueFactory(param -> { 
    final TreeItem<Car> item = param.getValue(); 
    final Car car = item.getValue(); 
    return new SimpleStringProperty(car.getModel()); 
});

Ici, nous avons créé une fabrique à valeur qui permettra d'afficher le modèle de la voiture dans la colonne modelColumn.

Mis à jour le 15 mars 2015 bouye

Pour changer l'apparence des objets contenus dans un TreeTreeView, nous avons besoin de faire appel à l'API Cell. En effet, l'affichage par défaut n'est pas très engageant :



Reprenons au début. Tout d'abord, nous avons dans notre arbre-table des instances de la classe TreeItem<Entity> qui vont nous permettre de stocker nos groupes ainsi que les diverses marchandises qui les composent :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private abstract static class Entity { 
  
    String name; 
} 
  
private final static class Group extends Entity { 
  
    public Group(final String name) { 
        this.name = name; 
    } 
} 
  
private static class Good extends Entity { 
  
    Image photo; 
    double price; 
  
    public Good(final String name, final Image photo, double price) { 
        this.name = name; 
        this.photo = photo; 
        this.price = price; 
    } 
}

Puis, nous nous sommes arrangés pour extraire les bonnes valeurs sur les bonnes colonnes :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
final TreeTableColumn<Entity, String> nameColumn = new TreeTableColumn("Nom"); 
nameColumn.setCellValueFactory(param -> { 
    final TreeItem<Entity> item = param.getValue(); 
    final Entity data = item.getValue(); 
    return new SimpleStringProperty(data.name); 
}); 
// 
final TreeTableColumn<Entity, Image> photoColumn = new TreeTableColumn("Photo"); 
photoColumn.setCellValueFactory(param -> { 
    final TreeItem<Entity> item = param.getValue(); 
    final Entity data = item.getValue(); 
    return (data instanceof Good) ? new SimpleObjectProperty<>(((Good) data).photo) : null; 
}); 
// 
final TreeTableColumn<Entity, Double> priceColumn = new TreeTableColumn("Prix au kilo"); 
priceColumn.setCellValueFactory(param -> { 
    final TreeItem<Entity> item = param.getValue(); 
    final Entity data = item.getValue(); 
    return (data instanceof Good) ? new SimpleObjectProperty<>(((Good) data).price) : null; 
}); 
// 
treeTableView.getColumns().setAll(nameColumn, photoColumn, priceColumn);

Nous allons donc maintenant coder quelques cellules pour l'image servant d’aperçu de nos fruits et légumes. Étant donné que le principe est similaire à ce que nous avons déjà vu sur TableView et TreeView, je ne vais pas m’étendre trop longtemps sur le sujet :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
photoColumn.setCellFactory(column -> new TreeTableCell<Entity, Image>(){ 
    private final ImageView imageView1 = new ImageView();             
    private final ImageView imageView2 = new ImageView();             
    private final Tooltip tooltip = new Tooltip(); 
  
    { 
        imageView1.setFitHeight(25); 
        imageView1.setPreserveRatio(true); 
        imageView1.setSmooth(true); 
        tooltip.setText(null); 
        tooltip.setGraphic(imageView2); 
    } 
  
    @Override 
    protected void updateItem(Image item, boolean empty) { 
        super.updateItem(item, empty);  
        setGraphic(null); 
        setText(null); 
        setTooltip(null); 
        if (!empty && item != null) { 
            imageView1.setImage(item); 
            imageView2.setImage(item); 
            setGraphic(imageView1); 
            setTooltip(tooltip); 
        } 
    }             
});

Ensuite, nous faisons de même pour le prix :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
priceColumn.setCellFactory(column -> new TreeTableCell<Entity, Double>(){ 
  
    @Override 
    protected void updateItem(Double item, boolean empty) { 
        super.updateItem(item, empty); 
        setText(null); 
        if (!empty && item != null) { 
            final String text = String.format("%.2f €", item.doubleValue()); 
            setText(text); 
        } 
    }             
});

Ici, la cellule étend TreeTableCell<Entity, Image> pour l’aperçu et TreeTableCell<Entity, Double> pour le prix.

Ce qui nous donne :



Les images des fruits et légumes affichées ici proviennent directement de leur article respectif sur Wikipédia.

Ici, désormais, nous affichons une image montrant notre produit et nous formatons correctement le prix pour notre utilisateur.

Mis à jour le 15 mars 2015 bouye

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsables bénévoles de la rubrique Java : Mickael Baron - Robin56 -