Gestionnaires de disposition

Les gestionnaires de disposition (layout manager en anglais) sont des objets responsables du positionnement des composants dans un conteneur. Ils permettent de décrire les positions relatives des composants dans un panneau sans donner les positions absolues. Ils offrent une grande souplesse de programmation. Le seul changement du gestionnaire de disposition peut complètement repositionner les composants.

Swing founit en standard plusieurs gestionnaires de disposition qui répondent à la très grande majorité des situations. Même si c'est une tâche très ardue, il est toujours possible d'écrire un autre gestionnaire de disposition spéficique à un problème particulier.

Les gestionnaires de disposition principaux en Java sont les suivants.

Tous ces gestionnaires implémentent l'interface LayoutManager et les gestionnaires BorderLayout, BoxLayout et GridBagLayout implémentent aussi l'interface LayoutManager2 qui étend l'interface LayoutManager. Ils existent aussi d'autres gestionnaires spécifiques comme ScrollPaneLayout qui ne sont pas utilisés directement par le programmeur. Le gestionnaire CardLayout est obsolète et il faut mieux utiliser un conteneur JTabbedPane.

Les gestionnaires par défaut sont BorderLayout pour

et FlowLayout pour

Le gestionnaire de disposition d'un conteneur peut être changé grâce à la méthode setLayout(LayoutManager). Si le gestionnaire est changé alors que le conteneur contient déjà des composants, il faut forcer la disposition en invoquant les méthodes doLayout() et revalidate().

Géométrie

Tout composant a un placement dans son conteneur qui est donné par son origine et ses dimensions qui détermine un rectangle. La classe JComponent possède les méthodes suivantes.

Les gestionnaires de disposition utilisent ces dimensions pour positionner au mieux les composants dans le conteneur.

Marges

Les conteneurs possèdes des marges entre leurs bords et les composants qu'ils contiennent. Ces marges sont de la classe Insets qui contient quatre champs de type int appelés top, left, bottom et right. Ces quatre champs donnent les tailles en pixels des quatre marges. La classe Insets possède un constructeur qui prend en paramètre les quatre marges.

Les conteneurs n'ont pas de méthode setInsets. Pour changer les marges, il faut redéfinir la méthode getInsets.

Validation

Tout composant est dit valide lorsqu'il est correctement dimensionné et positionné dans son conteneur et que ses fils sont aussi valides. La méthode isValid retourne si un composant est valide ou non. Les méthodes validate et invalidate rendent le composant respectivement valide et non valide.

La validation d'un composant consiste d'abord à dimensionner et positionner récursivement tous ses fils puis à valider ses ascendants jusqu'à trouver un conteneur de type validateRoot. En SWING, cette validation est différée tant qu'il y a des événements à délivrer. Pour forcer la validation d'un composant, il faut appeler la méthode revalidate. Cette méthode retrouve le premier ascendant de type validateRoot et le rend invalide. La validation s'effectuera sur tous les descendants de ce conteneur. La plupart du temps, la méthode revalidate est appelée automatiquement par SWING contrairement à AWT où il faut souvent appeler la méthode validate.

La méthode isValidateRoot retourne si un composant est de type validateRoot. Les éléments JRootPane, JScrollPane et JTextField sont de type validateRoot.

Revue des gestionnaires de disposition

FlowLayout

C'est le gestionnaire le plus simple. Il affiche ses composants de la gauche vers la droite et passe à la ligne lorsqu'une ligne est pleine. Les constructeurs principaux sont les suivants.

BorderLayout

Ce gestionnaire est assez spécifique mais il convient à de très nombreuse occasions. Il permet de contenir au plus cinq composants. Les cinq positions possibles d'un composants sont appelées NOTH, SOUTH, EAST, WEST et CENTER. Ce second paramètre est passé en plus à la méthode add lorsque un composant est ajouté au conteneur. Lorsque toutes les positions ne sont pas occupées, les composants se répartissent la place disponible.

GridLayout

Ce gestionnaire permet de disposer les composants sur une grille où chaque composant occupe la même place. Les contructeurs sont les suivants.

Un des deux nombres donnant le nombre de lignes et de colonnes peut être égal à zéro. Auquel cas, il n'est pas pris en compte et le nombre de lignes ou de colonnes s'adapte au nombre de composants.

BoxLayout

Ce gestionnaire permet de disposer des composants sur une seule ligne ou sur une seule colonne. Chacun des composants utilise une place variable en fonction de ses dimensions PreferredSize et MaximalSize. L'unique constructeur est le suivant.

Dans l'autre sens (que celui choisi pour mettre les composants), les composants sont alignés en fonction de leur paramètre aligmentX et alignmentY.

Ce gestionnaire est automatiquement utilisé par le conteneur Box qui permet en outre d'ajouter des espacements (strut) et de la glue (glue) extensible entre les composants. Les méthodes à utiliser sont les suivantes.

GridBagLayout

Ce gestionnaire permet de disposer les composants sur une grille où chaque composant occupe un nombre de lignes et de colonne variables. Il est d'une utilisation relativement compliquée. Son utilisation est basée sur la classe GridBagConstraints qui spéficie les différents paramètres. Un objet de cette classe est passé en second paramètre à la méthode add lorsque un composant est ajouté au conteneur.

Composition

Les dispositions complexes des interfaces complètes ne sont presque jamais obtenues par l'utilisation d'un seul gestionnaire de disposition dans un panneau. Elles le sont généralement par l'agencement de plusieurs gestionnaires associés à des panneaux imbriqués les uns dans les autres.