La souplesse de ce layout fait qu'il n'est pas nécessaire de créer des conteneurs intermédiaires de type JPanel ou Box. En revanche il faut créer un objet de type GridBagConstraints qui servira à définir les contraintes de mise en place de chaque composant.
On va repartir du programme Base et changer le layout de la fenêtre. Sauvegarder Base.java sous le nom GrilleSouple.java et faire les modifications de noms nécessaires, ainsi que celles indiquées ci-dessous en violet.
import javax.swing.*; import java.awt.*; class GrilleSouple extends JFrame{ JButton[] clavier=new JButton[12]; JTextField ecran; GrilleSouple(){ super(); setTitle("GridBagLayout"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); getContentPane().setLayout(new GridBagLayout()); ecran=new JTextField(); ecran.setFont(new Font(Font.SANS_SERIF,Font.PLAIN,34)); ecran.setBackground(Color.white); ecran.setEditable(false); for (int i=0;i<9;i++){ clavier[i]=new JButton(new Integer(i+1).toString()); } clavier[9]=new JButton("0"); clavier[10]=new JButton(","); clavier[11]=new JButton("C"); GridBagConstraints c=new GridBagConstraints(); c.gridx=0; c.gridy=0; c.gridwidth=3; c.gridheight=1; c.weightx=0.5; c.weighty=0.5; c.insets=new Insets(2,2,1,2); c.fill=GridBagConstraints.BOTH; getContentPane().add(ecran,c); c.gridwidth=1; c.insets=new Insets(1,1,1,1); for (int i=0;i<12;i++){ clavier[i].setFont(new Font(Font.SANS_SERIF,Font.BOLD,34)); c.gridx=i%3; c.gridy=1+i/3; getContentPane().add(clavier[i],c); } setLocation(400,400); setPreferredSize(new Dimension(250,450)); setMinimumSize(new Dimension(210,310)); pack(); setVisible(true); } public static void main(String[] args) { new GrilleSouple(); } }
La ligne
GridBagConstraints c=new GridBagConstraints();crée un objets de type GridBagConstraints.
On définit ensuite les contraintes de mise en place du JTextField :
c.gridx=0; c.gridy=0;place de l'élément :première ligne, première colonne
c.gridwidth=3; c.gridheight=1;élément occupant une ligne et trois colonnes
c.weightx=0.5; c.weighty=0.5;dimensions relatives "moyennes" (ces deux valeurs doivent être comprises entre 0 et 1)
c.insets=new Insets(2,1,1,1);marges extérieurs de 1 pixel en bas, à droite et à gauche de l'élément, et 2 pixels au-dessus (les marges sont indiquées dans l'ordre haut, gauche, bas, droite).
c.fill=GridBagConstraints.BOTH;l'élément remplira complètement , verticalement et horizontalement, l'emplacement attribué
getContentPane().add(ecran,c);place l'élément ecran en utilisant les contraintes définies.
Pour placer les boutons on modifie une partie des contraintes :
c.gridwidth=1;pour que chaque bouton occupe une seule colonne.
c.insets=new Insets(1,1,1,1);pour avoir des marges de 1 pixels autour de chaque bouton (ce qui fera 2 pixels entre les boutons)
Pour chaque bouton on détermine sa position dans la grille en fonction de son indice i en utilisant la division entière, comme vu précédemment . i%3 donne le numéro de colonne (de 0 à 2) et i/3+1 le numéro de rangée (de 1 à 4, la rangée 0 étant déjà occupée par le JTextField).
c.gridx=i%3; c.gridy=1+i/3;
Et on ajoute le bouton à la fenêtre en utilisant ces contraintes.
getContentPane().add(clavier[i],c);
Si on veut répartir équitablement les dimensions de tous les éléments de la grille, comme ici, on donne pour tous les éléments la même valeur non nulle à c.weightx et c.weighty . Si on voulait par exemple que l JTextField soit plutôt un peu plus haut que les boutons, on donnerait pour ceux-ci une valeur de weighty un peu plus faible.