Dans l'écosystème Java Swing, la gestion de la disposition des composants est fondamentale pour construire des interfaces utilisateur fonctionnelles et esthétiques. JGoodies FormLayout se présente comme un gestionnaire de mise en page robuste et flexible, offrant une approche structurée, inspirée des grilles, pour organiser les éléments d'interface.
Intégration de JGoodies FormLayout
Pour bénéficier des fonctionnalités de JGoodies FormLayout, la première étape consiste à inclure la bibliothèque dans votre projet. Si vous utilisez Maven, ajoutez la dépendnace suivante à votre fichier pom.xml :
<dependency>
<groupId>com.jgoodies</groupId>
<artifactId>forms</artifactId>
<version>1.9.0</version> <!-- Utiliser la dernière version stable -->
</dependency>
Une fois la dépendance ajoutée, vous pouvez commencer à utiliser FormLayout avec vos conteneurs Swing, tels que JPanel.
Définition des Spécifications de Colonnes et de Lignes
FormLayout fonctionne en définissant explicitement des spécifications pour chaque colonne et chaque ligne de votre mise en page. Ces spécifications déterminent la taille, le comportement de redimensionnement et l'alignement des cellules.
Types de Spécifications
Les spécifications sont définies à l'aide des classes ColumnSpec et RowSpec. Elles peuvent être créées à partir de chaînes de caractères (similaire à l'original) ou, de manière plus explicite et robuste, en utilisant des objets Sizes et des propriétés de ColumnSpec/RowSpec.
- Tailles Fixes : Permettent de définir une dimension exacte pour une colonne ou une ligne.
dlu(dialog units) : Unités de dialogue, adoptées à la résolution de l'écran. Ex:Sizes.dluX(4)pour une largeur de 4 DLU.px(pixels) : Taille en pixels. Ex:Sizes.pixel(100).pt(points),in(inches),mm(millimètres),cm(centimètres).
- Tailles Dynamiques : Ajustent les dimensions en fonction du contenu ou de l'espace disponible.
PREFERRED(pref) : La taille préférée du contenu de la cellule. Ex:Sizes.PREFERRED.MINIMUM(min) : La taille minimale du contenu de la cellule. Ex:Sizes.MINIMUM.DEFAULT(default) : Une taille par défaut pour le gestionnaire de mise en page.
Comportements de Redimensionnement
Ces comportements définissent comment les colonnes ou les lignes réagissent à l'espace disponible :
GROW(g) : La colonne/ligne s'étend pour occuper l'espace supplémentaire disponible. Un facteur de croissance peut être spécifié (ex:ColumnSpec.createCol(Sizes.DEFAULT, ColumnSpec.DEFAULT_GROW)ouColumnSpec.createCol(Sizes.DEFAULT, FormSpec.WEIGHT_1_2)pour un poids de 0.5).NO_GROW(n) : La colonne/ligne ne s'étire pas.
Alignement
L'alignement contrôle la position des composants dans leur cellule. Pour les colonnes, on utilise LEFT, CENTER, RIGHT, FILL. Pour les lignes, on a TOP, CENTER, BOTTOM, FILL.
Exemple de Définition des Spécifications
Voici comment définir un FormLayout avec des objets ColumnSpec et RowSpec :
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.layout.Sizes;
import javax.swing.JPanel;
// ...
// Définition des spécifications des colonnes
ColumnSpec[] specsColonnes = new ColumnSpec[] {
ColumnSpec.createCol(Sizes.PREFERRED), // Colonne 1: taille préférée du contenu
ColumnSpec.createGap(Sizes.dluX(4)), // Colonne 2: espace de 4 DLU
ColumnSpec.createCol(Sizes.DEFAULT_GROW) // Colonne 3: taille par défaut, s'étend avec l'espace
};
// Définition des spécifications des lignes
RowSpec[] specsLignes = new RowSpec[] {
RowSpec.createRow(Sizes.dluY(10)), // Ligne 1: hauteur fixe de 10 DLU
RowSpec.createRow(Sizes.PREFERRED), // Ligne 2: hauteur préférée du contenu
RowSpec.createGap(Sizes.dluY(5)), // Ligne 3: espace de 5 DLU
RowSpec.createRow(Sizes.DEFAULT) // Ligne 4: hauteur par défaut
};
// Création du FormLayout avec ces spécifications
FormLayout dispositionPanneau = new FormLayout(specsColonnes, specsLignes);
JPanel panneauContenu = new JPanel(dispositionPanneau);
Positionnement des Composants avec CellConstraints
Une fois le FormLayout configuré sur un JPanel, vous utilisez un objet CellConstraints pour spécifier la position et le comportement de chaque composant ajouté.
import com.jgoodies.forms.layout.CellConstraints;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
// ... (suite de l'exemple précédent) ...
CellConstraints cc = new CellConstraints();
// Ajout d'un libellé à la première colonne (index 1), deuxième ligne (index 2)
JLabel etiquetteChamp = new JLabel("Champ :");
panneauContenu.add(etiquetteChamp, cc.xy(1, 2));
// Ajout d'un champ de texte à la troisième colonne (index 3), deuxième ligne (index 2)
// Aligné sur le REMPLISSAGE horizontal et la valeur par défaut verticale
JTextField champSaisie = new JTextField("Texte ici");
panneauContenu.add(champSaisie, cc.xy(3, 2, CellConstraints.FILL, CellConstraints.DEFAULT));
// Ajout d'un bouton à la troisième colonne (index 3), quatrième ligne (index 4)
JButton boutonAction = new JButton("Appliquer");
panneauContenu.add(boutonAction, cc.xy(3, 4));
La méthode xy(col, row) est la plus simple. Des surcharges permettent de spécifier l'alignement (xy(col, row, colAlignment, rowAlignment)). Les constantes d'alignement sont disponibles dans CellConstraints (ex: CellConstraints.FILL, CellConstraints.LEFT, etc.).
Fusion de Cellules (Spanning)
FormLayout permet de fusionner des cellules, qu'elles soient adjacentes horizontalement (fusion de colonnes) ou verticalement (fusion de lignes).
Fusionner des Colonnes
La méthode xyw(col, row, colSpan) permet à un composant de s'étendre sur plusieurs colonnes.
col: Index de la colonne de départ.row: Index de la ligne de départ.colSpan: Nombre de colonnes sur lesquelles le composant doit s'étendre.
import javax.swing.JScrollPane;
import javax.swing.JTable;
import com.jgoodies.forms.builder.PanelBuilder; // Utile pour des builds plus fluides
import com.jgoodies.forms.layout.FormLayout;
// ...
FormLayout layoutFusionCol = new FormLayout(
"default, 4dlu, default:grow, 4dlu, default", // 5 colonnes avec espaces
"default, 4dlu, fill:default:grow" // 3 lignes
);
JPanel panneauFusionColonnes = new JPanel(layoutFusionCol);
CellConstraints ccf = new CellConstraints();
JLabel entete = new JLabel("Liste des éléments :");
panneauFusionColonnes.add(entete, ccf.xy(1, 1));
// Un tableau qui s'étend sur 3 colonnes (3, 4, 5) à partir de la ligne 3
JTable tableauDonnees = new JTable(new Object[][]{{"Item 1", 10}, {"Item 2", 20}}, new String[]{"Nom", "Valeur"});
panneauFusionColonnes.add(new JScrollPane(tableauDonnees), ccf.xyw(3, 3, 3));
Fusionner des Lignes et des Colonnes
Pour étendre un composant sur plusieurs lignes et colonnes, utilisez la méthode xywh(col, row, colSpan, rowSpan).
col: Index de la colonne de départ.row: Index de la ligne de départ.colSpan: Nombre de colonnes à couvrir.rowSpan: Nombre de lignes à couvrir.
import javax.swing.JTextArea;
// ...
FormLayout layoutFusionLigneCol = new FormLayout(
"default, 4dlu, default:grow, 4dlu, default", // 5 colonnes
"default, 4dlu, fill:default:grow, 4dlu, default" // 5 lignes
);
JPanel panneauFusionLignesColonnes = new JPanel(layoutFusionLigneCol);
CellConstraints cclc = new CellConstraints();
JLabel labelDescriptionDetaillee = new JLabel("Détails :");
panneauFusionLignesColonnes.add(labelDescriptionDetaillee, cclc.xy(1, 1));
// Une zone de texte qui s'étend sur 3 colonnes et 3 lignes
JTextArea zoneDetails = new JTextArea("Ceci est une description longue qui s'étend sur plusieurs cellules.");
zoneDetails.setRows(4); // Définir un nombre initial de lignes pour la zone de texte
zoneDetails.setLineWrap(true);
zoneDetails.setWrapStyleWord(true);
panneauFusionLignesColonnes.add(new JScrollPane(zoneDetails), cclc.xywh(3, 1, 3, 3));