Les Layout Managers en Java

AKA gestionnaires de placement

Cette page (créée par Mathieu Nancel) a pour but d'expliquer rapidement l'intérêt et le fonctionnement des gestionnaires de placement (Layout Managers) de Java et d'en présenter les plus courants.

Pour des exemples plus détaillés, voir la page des exemples du site de Java.
Pour des explications complètes, voir la page d'explications du site de Java.

Intérêt

Les gestionnaires de placement servent à indiquer à SWING comment disposer des éléments graphiques dans une fenêtre ou tout autre conteneur visuel. Ils sont indispensable au rendu ergonomique d'une application utilisant SWING.

Fonctionnement général

Les éléments graphiques disponibles dans la librairie SWING peuvent être des conteneurs, c'est-à-dire des éléments destinés à en contenir d'autres (par exemple une fenêtre). Lors du codage de votre application, vous allez d'abord créer des conteneurs, puis les remplir d'élements de plus haut niveau (texte, menus, listes, etc.). Au moment de l'ajout d'un élément dans un conteneur, SWING va interroger le LayoutManager du conteneur pour savoir où et comment afficher cet élément. Il faut donc attribuer un LayoutManager à un conteneur avant d'y ajouter des éléments.

Cas général pour une fenêtre (JFrame):

	JFrame frame = new JFrame("Ma fenêtre");   // Une fenêtre SWING simple
	Container pane = frame.getContentPane();   // Le Container par défaut d'une fenêtre SWING, c'est là qu'il faut ajouter des élements
	pane.setLayout(...);                       // Le LayoutManager choisi et ses éventuelles options
	
	JButton button = new JButton("Mon bouton");// Un bouton pour l'exemple
	frame.add(button);                         // Cas simple
	// frame.add(button, constraints);         // Cas avec contraintes, les contraintes dépendent du LayoutManager
		

Les principaux types de layout et leur utilisation

Le BorderLayout

Le BorderLayout est le gestionnaire de placement par défaut d'une fenêtre. Il sépare le conteneur en 5 zones qui correspondent grosso modo aux zones de placement habituelles d'une fenêtre:

Généralement:

PAGE_START, LINE_START, CENTER, LINE_END et PAGE_END sont des constantes de la classe BorderLayout et en constituent les contraintes:

	// [...]
	frame.add(button, BorderLayout.PAGE_END);
		

Javadoc Tutoriel


Le BoxLayout

Le BoxLayout est un LayoutManager simple permettant d'aligner des éléments verticalement (Y_AXIS) ou horizontalement (X_AXIS). Il propose aussi d'autres fonctionnalités d'alignement simples.

Les composants sont représentés dans l'ordre d'ajout dans le code.

	JFrame frame = new JFrame("Ma fenêtre");
	Container pane = frame.getContentPane();
	pane.setLayout(new BoxLayout(pane, Y_AXIS));    // Un BoxLayout sur pane orienté verticalement
	JButton button = new JButton("Mon bouton");
	frame.add(button);                              // Pas de contraintes avec BoxLayout
		

Javadoc Tutoriel


Le GridLayout

Le GridLayout permet de disposer des éléments sous forme de grille, comme dans un tableur. Les lignes ont toutes la même hauteur, les colonnes ont toutes la même largeur, et un élément ne peut pas être dans deux “cases” à la fois.

Le nombre de lignes et de colonnes est défini à la création du GridLayout. Les éléments sont ensuite représentés dans l'ordre d'ajout dans le code (par défaut, de gauche à droite et de haut en bas).

	JFrame frame = new JFrame("Ma fenêtre");
	Container pane = frame.getContentPane();
	pane.setLayout(new GridLayout(0, 2));         // Un GridLayout avec deux colonnes et un nombre indéfini de lignes
	JButton button = new JButton("Mon bouton");
	frame.add(button);                            // Pas de contraintes avec GridLayout
		

Le nombre de lignes et colonnes peut être défini à la création. Comme montré dans l'exemple, la valeur 0 indique un nombre indéfini de lignes ou colonnes. Le constructeur par défaut new GridLayout() représente une ligne et un nombre indéfini de colonnes.

Javadoc Tutoriel


Le GridBagLayout

Le GridBagLayout est un des LayoutManagers les plus flexibles mais aussi l'un des plus complexes. Il permet d'afficher les éléments ajoutés dans une grille, comme le GridLayout, mais avec beaucoup plus de possibilités (tailles de lignes et de colonnes différentes, éléments sur plusieurs emplacements, etc.).

Le GridBagLayout a son propre système de contraintes via la classe GridBagConstraints. Une instance de cette classe contient différents paramètres permettant de contrôler l'affichage de chaque élément. Parmi les plus utiles :

Les paramètres d'un GridBagConstraints sont lus lors de l'ajout d'un élément dans le conteneur. Le développeur peut coder un GridBagConstraints par élément à ajouter, ou réutiliser le même pour tous les éléments en changeant les valeurs entre deux ajouts. Cependant, cette stratégie peut introduire des bugs si le développeur ne fait pas très attention.

	JFrame frame = new JFrame("Ma fenêtre");
	Container pane = frame.getContentPane();
	pane.setLayout(new GridBagLayout());
	GridBagConstraints c = new GridBagConstraints();    // Pas de paramètres
	
	c.gridx = 0;                                        // Première colonne
	c.gridy = 1;                                        // Deuxième ligne
	c.gridheight = 2;                                   // Dépasse sur la colonne d'en dessous
	c.fill = GridBagConstraints.VERTICAL;               // L'élément doit être étiré en hauteur si besoin est
	JButton button = new JButton("Mon bouton");
	frame.add(button, c);
		

Javadoc Tutoriel


Combiner des LayoutManagers

Un moyen simple d'obtenir des placements évolués sans recourir aux GridBagLayouts est de combiner des LayoutManagers à l'aide de l'élément SWING JPanel. Un JPanel est un élément vide qui peut en contenir d'autres. Il est donc facile de donner un LayoutManager à une fenêtre et d'en appliquer localement un ou plusieurs autres. Attention cependant, un conteneur ne peut avoir qu'un LayoutManager.