8.1 Arbres

Écrit par Neil Deakin , mise à jour par les contributeurs à MDC .
Traduit par Damien Hardy (10/04/2004), mise à jour par Alain B. (04/04/2007) .
Page originale : http://developer.mozilla.org/en/docs/XUL_Tutorial/Trees

Attention : Ce tutoriel est ancien et n'est pas mis à jour. Bien que beaucoup d'informations soient encore valables pour les dernières versions de gecko, beaucoup sont aussi obsolètes. Il est préférable d'aller consulter cette page sur la version française de ce tutoriel sur developer.mozilla.org.

XUL fournit un moyen de créer des listes tabulaires ou hiérarchiques en utilisant un arbre.

L'élément tree

Un des éléments les plus complexes de XUL est l'arbre. Un arbre peut être utilisé pour afficher des lignes de texte en colonnes. Il peut servir pour des listes tabulaires ou arrangées hiérarchiquement. Un arbre permet également à l'utilisateur de réarranger, redimensionner et masquer individuellement certaines colonnes. Les messages dans une application courrier ou les marque-pages dans Mozilla sont des exemples d'utilisation d'arbres.

D'une certaine manière, un arbre a des similitudes avec une boîte de liste listbox. Tous deux peuvent être utilisés pour créer des tableaux de données avec des lignes et des colonnes multiples, et ils peuvent contenir des en-têtes de colonnes. Les arbres supportent également les lignes imbriquées, alors que les boîtes de liste ne le peuvent pas. Toutefois, les boîtes de liste peuvent contenir n'importe quel type de contenu, alors que les arbres ne peuvent contenir que du texte et des images (par le biais de fonctionnalités avancées, des barres de progression et cases à cocher peuvent également être mis dans un arbre).

Un arbre comporte deux parties : un ensemble de colonnes et le corps de l'arbre.

L'arbre est un élément XUL particulier dans le sens où son corps est constitué d'un seul composant graphique qui dessine toutes les données dans l'arbre. Cette définition contraste avec la boîte de liste où des balises individuelles listitem et listcell sont utilisées pour spécifier chaque ligne dans l'élément listbox. Dans un arbre, toutes les données à afficher sont fournies par un objet séparé, appelé la vue d'arbre. Lorsqu'une cellule doit être affichée, le composant graphique de l'arbre fait appel à cet objet de vue d'arbre pour déterminer ce qui doit être affiché, et le dessine ensuite dans l'arbre. L'arbre est suffisamment intelligent pour ne solliciter les informations de la vue que pour les lignes qui ont besoin d'être affichées. Ainsi, l'affichage est optimisé par le chargement des données le nécessitant réellement. Par exemple, un arbre peut contenir des milliers de lignes, la plupart d'entre elles étant en dehors du cadre de l'arbre, cachées à la vue. Ainsi, l'arbre peut contenir un grand nombre de lignes sans rien perdre en performance. Bien entendu, ceci est indépendant de la performance de l'objet de vue lui-même.

L'objet vue d'arbre implémente l'interface nsITreeView. Cette interface contient trente propriétés et fonctions que vous pourrez implémenter. Ces fonctions seront appelées par l'arbre, au besoin, pour récupérer les données et les états de l'arbre. Par exemple, la fonction getCellText() sera appelée pour obtenir le libellé d'une cellule particulière dans l'arbre.

L'utilisation d'une vue a l'avantage de vous permettre de stocker vos données d'une façon plus adaptée à l'arbre, ou de charger les données sur demande seulement lorsque les lignes sont affichées. Elle offre une plus grande souplesse dans l'utilisation des arbres.

Naturellement, devoir implémenter une vue d'arbre avec une trentaine de propriétés et méthodes peut être très encombrant, surtout pour des arbres simples. Fort heureusement, XUL fournit un ensemble d'implémentations natives réalisant le gros du travail pour vous. Pour la plupart des arbres, surtout lorsque vous débutez, vous utiliserez un de ces types natifs. Cependant, vous pouvez créer également une vue d'arbre entièrement de A à Z. Dans ce cas, vous devrez stocker vos données dans un tableau ou une structure JavaScript, ou les charger à partir d'un fichier XML.

Comme le corps de l'arbre dans sa totalité est un unique élément graphique, vous ne pouvez pas modifier le style des lignes ou des cellules individuellement de manière classique. En fait, il n'existe pas d'éléments affichant des cellules individuelles comme il en existe avec les boîtes de liste. À la place, tout l'affichage est effectué par le corps de l'arbre grâce aux données fournies par la vue de l'arbre. Ce point important peut dérouter bien des développeurs XUL. Pour modifier l'apparence d'une cellule d'un arbre, la vue doit associer un jeu de mots clefs pour une ligne et une cellule. Une syntaxe CSS spéciale est employée entre les composants de styles du corps d'un arbre grâce à ces mots clefs. Dans un sens, le mécanisme est similaire aux classes CSS. L'application d'un style à un arbre sera détaillée dans une section ultérieure.

Les éléments d'arbre

Les arbres sont créés avec l'élément tree qui sera décrit dans les prochaines sections. Il existe également deux éléments définissant l'affichage des colonnes dans l'arbre.

tree
L'élément entourant d'un arbre
treecols
L'élément initialisant une série de treecol
treecol
Cet élément déclare une colonne d'arbre. Avec l'utilisation de cet élément, vous pouvez spécifier des informations supplémentaires sur le tri des données en colonne ou encore la possibilité ou non pour l'utilisateur de redimensionner les colonnes. Vous devez toujours placer un attribut id sur une colonne, car Mozilla utilise cet identifiant pour les colonnes à réarranger ou à masquer. Il n'est plus nécessaire sous les versions 1.8 et suivantes de Mozilla, mais c'est une bonne habitude à conserver.
treechildren
Cet élément contient le corps principal de l'arbre, là où les lignes individuelles de données seront affichées

Voici un exemple d'arbre avec deux colonnes :

Exemple 8.1.1 : Source Voir

<tree flex="1">

  <treecols>
    <treecol id="nameColumn" label="Nom" flex="1"/>
    <treecol id="addressColumn" label="Adresse" flex="2"/>
  </treecols>

  <treechildren/>

</tree>

Tout d'abord, l'ensemble du tableau est entouré avec l'élément tree. Il déclare un élément qui servira de tableau ou d'arbre. Comme avec les tables HTML, les données d'un arbre sont toujours organisées en lignes. Les colonnes sont spécifiées grâce à la balise treecols.

Vous pouvez mettre dans un arbre autant de colonnes que vous le souhaitez. Comme pour les boîtes de listes, une ligne d'en-tête apparaîtra avec les libellés des colonnes. Un menu déroulant apparaîtra dans le coin supérieur droit de l'arbre et permettra à l'utilisateur d'afficher ou de masquer les colonnes individuellement. Chaque colonne est créée avec l'élément treecols. Vous pouvez définir le libellé d'en-tête en utilisant l'attribut label. Vous pouvez également rendre vos colonnes flexibles si votre arbre l'est aussi, ainsi les colonnes s'ajusteront en fonction de l'arbre. Dans cet exemple, la seconde colonne sera deux fois plus large que la première. Toutes les colonnes doivent être définies à l'intérieur de l'élément treecols.

Dans ce cas, nous n'avons pas indiqué à la vue les données de l'arbre, seuls les en-têtes de colonnes et un arbre vide seront visibles. Vous pouvez redimensionner la fenêtre, mais rien n'apparaîtra puisqu'il n'y a aucune donnée à afficher. Puisque la flexibilité de l'arbre a été spécifiée, son corps s'ajustera à l'espace disponible. La flexibilité d'un arbre est couramment appliquée, car les données de l'arbre sont souvent les informations les plus significatives affichées, donc il est logique que l'arbre puisse ajuster sa dimension. Toutefois, vous pouvez spécifier un nombre de lignes à afficher dans l'arbre en affectant l'attribut rows sur l'élément tree. Notez que cet attribut indique le nombre de lignes qui seront affichées dans l'interface utilisateur et non le nombre de lignes de données. Le nombre total de lignes de données est fourni par la vue d'arbre. S'il y a trop de lignes de données à afficher dans l'arbre, une barre de défilement apparaîtra pour permettre à l'utilisateur de visualiser le reste. Si vous ne spécifiez aucun attribut rows, la valeur par défaut sera 0 signifiant qu'aucune ligne ne s'affichera. Dans ce cas, vous devrez rendre votre arbre flexible. Si votre arbre est flexible, il n'a pas besoin d'un attribut rows puisqu'il s'ajustera toujours à l'espace disponible.

Le contenu de la vue d'arbre

Nous avons vu que les données à afficher dans un arbre proviennent d'une vue et non de balises XUL, en passant par une construction interne de la vue d'arbre à partir des balises XUL. Ce mécanisme peut paraître légèrement confus. Retenez simplement que la construction des vues d'arbre emploie une série de balises servant à définir l'information sur les données dans l'arbre. Les éléments suivants sont utilisés :

treeitem
Il contient une unique ligne de niveau supérieur et tous ses descendants. Il sert également d'item pouvant être sélectionné par l'utilisateur. La balise treeitem entoure une toute une ligne en permettant de la sélectionner entièrement.
treerow
Une seule ligne d'un arbre devant être placée à l'intérieur d'une balise treeitem.
treecell
Une seule cellule d'un arbre. Cet élément est placé à l'intérieur d'un élément treerow.

Par convention, ces balises peuvent être placées directement à l'intérieur de la balise treechildren, imbriquées dans l'ordre mentionné ci-dessus. Ces balises définissent les données à afficher dans le corps de l'arbre. Dans ce cas, l'arbre utilise la construction interne de la vue d'arbre, appelée le contenu de la vue d'arbre, qui utilise les libellés et les valeurs spécifiés sur ces éléments comme données pour l'arbre. Lorsque l'arbre a besoin d'afficher une ligne, il demande à la vue d'arbre le libellé de la cellule en appelant la fonction getCellText() de la vue qui, dans la continuité, obtient la donnée de l'élément treecell correspondant.

Cependant, les trois éléments listés ci-dessus ne sont pas affichés directement. Ils ne sont utilisés que comme source de données pour la vue. Ainsi, seuls des attributs utiles sont appliqués sur l'élément treeitem et les éléments associés. Par exemple, vous ne pouvez pas modifier l'apparence des lignes d'un arbre en utilisant un attribut style ou d'autres propriétés CSS, et les fonctionnalités existantes pour les boîtes, telles que la flexibilité et l'orientation, ne peuvent pas être employées.

En fait, à part quelques attributs spécifiques aux arbres, les seuls qui auront un effet sont l'attribut label pour définir un texte libellé d'une cellule et l'attribut src pour définir une image. Toutefois, dans les sections ultérieures, nous verrons des moyens spéciaux de modifier le style d'un arbre et d'appliquer d'autres fonctionnalités.

De même, les événements ne sont pas générés par un élément treeitem et ses enfants ; en revanche, ils seront générés par l'élément treechildren.

Le fait que les éléments treeitem soient si différents des autres éléments XUL est une source classique de confusion pour les développeurs XUL. Essentiellement, le contenu de la vue d'arbre est une vue où les données des cellules sont fournies à partir des balises placées à l'intérieur de l'arbre. Naturellement, si vous utilisez un type différent de vue, les données seront fournies par une autre source, et il n'y aura aucun élément treeitem du tout.

Commençons par regarder comment créer un arbre simple avec des colonnes multiples en utilisant la vue d'arbre de contenu. Il pourrait servir à créer une liste de messages mél (mails). Il y aura plusieurs colonnes, telles que l'expéditeur et le sujet.

Exemple avec treechildren

Exemple 8.1.2 : Source Voir

<tree flex="1">

  <treecols>
    <treecol id="sender" label="Expéditeur" flex="1"/>
    <treecol id="subject" label="Sujet" flex="2"/>
  </treecols>

  <treechildren>
    <treeitem>
      <treerow>
        <treecell label="joe@somewhere.com"/>
        <treecell label="Plans Top secret"/>
      </treerow>
    </treeitem>
    <treeitem>
      <treerow>
        <treecell label="mel@whereever.com"/>
        <treecell label="Invitation à déjeuner"/>
      </treerow>
    </treeitem>
  </treechildren>
</tree>

Comme vous pouvez le voir sur cette image, l'arbre a été créé avec deux lignes de données.

Cet arbre a deux colonnes dont la seconde occupe plus de place que la première. Vous rendrez généralement les colonnes flexibles. Vous pouvez également imposer les largeurs grâce à l'attribut width. Vous devez inclure le même nombre d'éléments treecol qu'il y a de colonnes dans l'arbre. Dans le cas contraire, des choses étranges pourraient se produire.

Les en-têtes sont créés automatiquement. Le bouton situé dans le coin supérieur droit sert à afficher ou à masquer les colonnes. Vous pouvez placer un attribut hidecolumnpicker sur l'élément tree et le définir à true si vous désirez masquer ce bouton. Si ce bouton est masqué, l'utilisateur ne sera pas en mesure de masquer des colonnes.

Assurez-vous d'avoir défini un attribut id sur chaque colonne, sinon les actions de masquage et d'affichage ne fonctionneront pas avec toutes les versions de Mozilla.

L'élément treechildren entoure toutes les lignes. Les lignes individuelles à l'intérieur du corps peuvent contenir d'autres lignes. Pour l'arbre le plus simple, chaque ligne est créée avec les éléments treeitem et treerow. L'élément treerow entoure toutes les cellules d'une ligne, tandis que l'élément treeitem entoure une ligne et tous ses enfants. Les arbres avec des lignes imbriquées seront décrits dans la section suivante.

Dans les cellules, vous placerez les cellules individuelles. Elles sont créées avec l'élément treecell. Vous pouvez définir un texte dans une cellule en utilisant l'attribut label. Le premier élément treecell d'une ligne détermine le contenu qui apparaîtra dans la première colonne, le deuxième élément treecell détermine le contenu qui apparaîtra dans la deuxième colonne, et ainsi de suite.

L'utilisateur peut sélectionner les items de l'arbre en cliquant sur eux avec la souris, ou en mettant en surbrillance avec le clavier. Il peut en sélectionner plusieurs en maintenant la touche Maj ou Ctrl appuyée et en cliquant sur d'autres lignes. Pour désactiver la sélection multiple, placez un attribut seltype sur l'élément tree avec la valeur single. Ainsi, l'utilisateur ne pourra sélectionner qu'une seule ligne à la fois.

Ajout d'un arbre sur notre exemple de recherche de fichiers

Ajoutons un arbre à notre exemple de recherche de fichiers dans lequel les résultats de la recherche seront affichés. L'arbre utilisera une vue de contenu d'arbre. Le code suivant doit être ajouté à la place de la balise iframe.

Exemple : Source Voir

<tree flex="1">
  <treecols>
    <treecol id="name" label="Nom de fichier" flex="1"/>
    <treecol id="location" label="Emplacement" flex="2"/>
    <treecol id="size" label="Taille" flex="1"/>
  </treecols>

  <treechildren>
   <treeitem>
     <treerow>
       <treecell label="mozilla"/>
       <treecell label="/usr/local"/>
       <treecell label="2520 bytes"/>
     </treerow>
   </treeitem>
  </treechildren>
</tree>

<splitter collapse="before" resizeafter="grow"/>

Nous avons ajouté un arbre avec les trois colonnes Nom de fichier, Emplacement et Taille. La deuxième colonne sera deux fois plus large grâce à une flexibilité plus grande. Une seule ligne a été ajoutée pour les besoins de la démonstration de l'apparence du tableau avec une ligne. Dans une implémentation réelle, les lignes seront ajoutées par un script à l'issue de la recherche, ou une vue personnalisée sera créée pour contenir les données.


Nous verrons ensuite comment créer des arbres plus complexes.


Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™ sont des marques de la fondation Mozilla.