Tous les systèmes d'exploitation moderne sont maintenant 
dotés d'interfaces graphiques. Pour assurer l'indépendance de JAVA par rapport 
à la plate-forme, les concepteurs aurait pu concevoir des composants graphiques 
spécifiques. Ils ont préféré réutiliser les composants de la machine client 
au moyen d'interfaces implantés dans la machine virtuelle du navigateur.  La 
gestion des composants graphiques est basée sur la notion de conteneurs 
qui sont des espaces graphiques destinés à recevoir plusieurs composants comme 
des boutons, des cases à cocher ... dont la mise en place graphique est 
fonction d'un protocole de mise en page. En effet, selon les systèmes 
d'exploitation, la taille et l'aspect de ces composants varient et il se pose 
le problème de leur positionnement.
 La classe Applet dérive 
de la classe Panel qui est une extension de la classe abstraite Container. 
La classe Panel (panneau) représente des conteneurs qui sont placés dans un 
espace graphique existant pouvant être un autre Panel : une applet étant 
un Panel peut donc contenir d'autres Panels (système récursif).
     Avant 
d'examiner au chapitre suivant les composants graphiques gérés par JAVA, nous 
allons maintenant examiner les différents gestionnaires de mise en page associés 
aux conteneurs. 
C'est la mise en page par défaut (elle est utilisée quand aucun protocole 
n'est précisé). Dans cette mise en page "glissante", les composants graphiques sont ajoutés 
les uns après les autres de gauche à droite avec un saut de ligne quand il n'y 
a plus de place à droite. L'aspect final dépend donc de la taille de la fenêtre 
de l'applet.
Les trois constructeurs possibles possèdent  la syntaxe :
FlowLayout( 
), FlowLayout(int align) et  FlowLayout(int align, int dx, int 
dy). dx et dy précisent l'écartement des composants en x et y.
Les constantes FlowLayout.LEFT = 0, FlowLayout.CENTER 
= 1 (défaut) et FlowLayout.RIGHT = 2 précisent l'alignement (align) dans une 
ligne. 
Dans l'exemple suivant, on utilise comme composants un tableau de 4 boutons. La taille des boutons est fonction de la fonte utilisée : il est donc essentiel de définir celle-ci. La valeur de la constante pos est passée à l'applet par une balise <param>. On peut constater l'évolution de l'aspect final en fonction de la taille de l'applet. Remarquez aussi que seule la surface des composants masque la zone de dessin.
import java.applet.*;
import 
java.awt.*;
public class layflow extends 
Applet
{ Button bt[] = new Button[4];  //déclaration 
des boutons
  Font 
font= new Font("TimesRoman",0,12);
  FlowLayout fl;  //déclaration 
du gestionnaire
  int 
p;
  public void init()
  {  setBackground(Color.lightGray);
     setFont(font);
     p 
= Integer.parseInt(getParameter("pos")); //récupération 
de pos
     fl 
= new FlowLayout(p,15,8);        //création 
du gestionnaire
     setLayout(fl); 
   //mise 
en place
     for 
(int i=0; i<5; i++){
        bt[i]=new 
Button(" Bouton "+(i+1)); //création 
des boutons
        add(bt[i]);}} 
// méthode add( ) pour la mise 
en place des boutons
  public void paint(Graphics 
g)
  {  g.setFont(font);
     g.drawString("Test 
de flowLayout avec pos = "+p, 40, 100);
     g.drawLine(0,0,size().width,size().height);}
}
| 
             
  | 
    |
| 
             
  | 
        
             
  | 
    
Dans tous les cas de mise en place simple avec peu de composants il faut utiliser ce gestionnaire.
La mise en place glissante offre peu de possibilité pour les mises en page complexes. Le protocole de spécification par les bords BorderLayout décompose le conteneur en 5 zones (précisées par les constantes North, South, East, West et Center) qui peuvent recevoir chacune un seul composant. Le constructeur BorderLayout(int dx, int dy) permet de préciser l'espace entre les composants selon x et y. Les dimensions des composants sont fonctions des dimensions du container mais leurs positions sont maintenant définies. L'exemple ci-dessous indique comment utiliser ce gestionnaire.
import java.applet.*;
import 
java.awt.*;
public class layborder extends 
Applet
{ Button bt[]=new Button[5];
  Font font= new Font("TimesRoman",0,12);
  BorderLayout 
fl;
  public void init()
  {  setBackground(Color.lightGray);
     setFont(font);
     fl 
= new BorderLayout(10,30);//création 
du gestionnaire
     setLayout(fl);
    for 
(int i=0; i<5; i++)
        bt[i]=new 
Button(" Bouton "+(i+1));//création 
des boutons
    add("North",bt[0]);     add("South",bt[1]);//mise 
en place
    add("East",bt[2]);      add("West",bt[3]);
    add("Center",bt[4]);    }
  public void paint(Graphics 
g)
  {  g.setFont(font);
     g.drawString("Test 
de BorderLayout",40,110);
     g.drawLine(0,0,size().width,size().height);}
}
    Avec cet exemple simpliste ce protocole semble peu intéressant puisque chaque 
composant graphique occupe toute la place qui lui est offerte. C'est ici que l'on peut 
faire intervenir la récursivité des protocoles : un conteneur 
est lui-même un composant graphique qui peut contenir d'autres conteneurs.
 
Le conteneur le mieux adapté est le panneau (Panel). Avec cette technique, il 
est possible de concevoir des mises en page d'applets assez complexes avec un 
code relativement simple.
Ainsi dans l'exemple suivant, nous allons placer 
des composants dans le haut et dans le bas de l'applet en utilisant deux objets 
panneaux dotés chacun de son propre gestionnaire de mise en page. Pour 
la mise en place des boutons dans chaque panneau, on utilise la méthode add( 
) de l'instance de Panel utilisée.
import java.applet.*;
import 
java.awt.*;
public class layborder2 extends 
Applet
{  Button bt[]=new Button[5];
   Font 
font= new Font("TimesRoman",0,12);
   Font bold= 
new Font("TimesRoman",1,14);
   Panel Panor=new 
Panel(), Pasud=new Panel(); //création 
des Panels
   BorderLayout 
fl= new BorderLayout(10,30);   //Protocole 
principal
  
   public void 
init()
   { setBackground(Color.lightGray);
     setFont(font); 
//fonte pour les composants
     setLayout(fl);
     add("North",Panor);     add("South",Pasud); 
//ajout des panneaux
     Panor.setLayout(new 
FlowLayout(1,20,5));   //protocole 
du panneau supérieur
     Pasud.setLayout(new 
FlowLayout(2,30,10));  //protocole 
du panneau inférieur
     for 
(int i=0; i<5; i++)  //création 
des boutons
       bt[i]=new 
Button(" Bouton "+(i+1));
     for (int 
i=0; i<3; i++) Panor.add(bt[i]); //mise 
en place des boutons du haut
     for 
(int i=3; i<5; i++) Pasud.add(bt[i]);} 
  public void paint(Graphics 
g)
  {  g.setFont(bold); //fonte 
pour l'applet
     g.drawString("Test 
de BorderLayout avec Panels",40,80);
     g.drawLine(0,0,size().width,size().height);}
}
Attention : Les Panels ainsi mis en place limitent la surface de dessin de l'applet !
 Ce protocole définit une grille dont chaque cellule peut contenir un 
composant graphique. Les composants sont ajoutés de gauche à droite ligne par 
ligne. Utilisé seul ce gestionnaire n'a pas beaucoup d'intérêt. Par contre utilisé 
avec un protocole BorderLayout et des panneaux, il permet des mises en page 
intéressantes. Il existe deux constructeurs GridLayout( int lig, int col) 
et GridLayout( int lig, int col, int dx, int dy); lig indique 
le nombre de lignes de la grille et col son nombre de colonnes; dx 
et dy précisent l'écartement entre les composants.
Dans l'exemple 
suivant, on met en place dans un panneau Pasud un autre panneau PasuW doté d'un 
protocole Grid Layout qui va contenir 10 boutons. Il est en effet impossible 
de placer directement ce protocole dans Pasud car alors les composants occuperaient 
toute la largeur offerte. La surface en dessous du trait horizontal n'est plus 
disponible pour le dessin (elle est occupée par le panneau Pasud) mais peut elle peut éventuellement 
contenir des composants.
 import java.applet.*;
import java.awt.*; 
public class laygrid extends Applet
{ Button bt[]=new Button[3];
  Button bu[]=new Button[10];
  Font font= new Font("TimesRoman",0,14);
  Font bold= new Font("TimesRoman",1,12);
  Panel Panor=new Panel(), 
Pasud=new Panel();
  Panel PasuW=new Panel(); //container 
pour les boutons bu
  BorderLayout fl= new BorderLayout(10,10); 
  public void init()  
  {  setBackground(Color.lightGray);
     Panor.setFont(font);   Pasud.setFont(bold); 
//choix des fontes
     setLayout(fl);
     add("North",Panor);     add("South",Pasud);
     Panor.setLayout(new 
FlowLayout(1,20,5)); //protocoles 
des panneaux
     Pasud.setLayout(new 
FlowLayout(0,5,5));  //principaux
     Pasud.add(PasuW); 
   //1 
panneau dans un autre
     PasuW.setLayout(new 
GridLayout(4,3,5,5));
         //avec 
son gestionnaire (une grille de 4 lignes de 3 colonnes)
     for 
(int i=0; i<3; i++)  //création 
des boutons bt
        bt[i]=new 
Button(" Bouton "+(i+1)); 
     for 
(int i=0; i<10; i++)  //création 
des boutons bu
        bu[i]=new 
Button(" "+i+" "); 
     for 
(int i=0; i<3; i++) Panor.add(bt[i]); //et 
mise en place
     for 
(int i=1; i<10; i++) PasuW.add(bu[i]);
     PasuW.add(bu[0]);} 
 public void paint(Graphics 
g)
 {  g.setFont(font);
    g.drawString("Test 
de GridLayout avec Panels",20,70);
    g.drawLine(0,118,320,118); 
//pour contrôle de la 
zone utile
    g.drawLine(0,size().height,size().width,0);}
}
Il existe également le gestionnaire CardLayout qui ne peut afficher qu'un seul composant à la fois (en général un panneau qui va posséder ses propres composants).Ce gestionnaire est doté de méthodes first( ), last( ), previous( ) et shows( ) qui permettent de naviguer entre les cartes. Ceci suppose la mise en place de boutons de navigation sur chaque carte.
    Enfin pour les situations complexes, existe le protocole 
GridBagLayout qui fonctionne avec des contraintes précisées par la classe 
GridBagConstraints. Dans ce gestionnaire chaque composnt est inséré dans 
un conteneur et on lui associe une contrainte qui précise son emplacement dans 
une grille, sa taille...
Ce protocole est très lourd à mettre en oeuvre et 
je ne le décrirai pas car il existe (à mon avis) une méthode beaucoup plus facile 
à mettre en application dans les applets qui est la méthode sans gestionnaire.
     Dans une applet, la taille de la fenêtre est imposée par les paramètres 
width et height de la balise <applet>. Il est donc possible de prévoir 
l'aspect final de l'applet dans le navigateur si la taille des composants est 
connue. Il existe pour les composants la méthode reshape(int ox, int oy, 
int large, int haut) qui permet d'imposer au composant sa position (ox, 
et oy) et ses 
dimensions (large et haut) à condition qu'un gestionnaire de mise en page ne soit pas actif.
Comme par défaut JAVA utilise un protocole FlowLayout, il faut commencer par 
déclarer que celui-ci est inactif au moyen de l'instruction FlowLayout fl 
= null. On peut ensuite placer les composants dans la fenêtre aux endroits 
souhaités. Cette technique suppose que la fonte utilisée pour les composants 
soit définie dès le départ. Comme exemple, on va reprendre le cas précédent. 
On peut constater que cette technique est beaucoup plus souple au niveau du 
positionnement des composants. On peut aussi constater qu'aucun panneau ne vient 
masquer la surface de l'applet.
Remarque : depuis la version 1.1, la méthode reshape( 
) a été remplacée par la méthode setBounds( ) qui possède les 
mêmes arguments (en fait seul le nom de la méthode a changé).
import java.applet.*;
import 
java.awt.*;
public class laynull extends 
Applet
{ Button bt[]=new Button[3];
  Button bu[]=new Button[10];
  Font 
font= new Font("TimesRoman",0,14);
  Font bold= new Font("TimesRoman",1,12);
  FlowLayout 
fl= null; //essentiel
  public void init()  
  { setBackground(Color.lightGray);
    setLayout(fl); 
   //essentiel
    for 
(int i=0; i<3; i++){
      bt[i]=new Button("Bouton 
"+(i+1));//création
      add(bt[i]); 
   //ajout
      bt[i].setFont(font); 
//fonte du composant
      bt[i].reshape(20+100*i,5,80,22);} 
//mise en place
    setFont(bold); 
//fonte par défaut pour 
les composants à venir
    for 
(int i=0; i<10; i++)
      bu[i]=new Button(" 
"+i+" ");//création
    int k=0;
    for 
(int l=80; l<150; l+=30){
      for (int 
c=0; c<3; c++){
        k++;
        add(bu[k]); 
//ajout
        bu[k].reshape(100+30*c,l,25,25);}}//mise 
en place
    add(bu[0]);
    bu[0].reshape(130,170,25,25);}        
  public void paint(Graphics 
g)
  { g.setFont(font);
    g.drawString("Test 
sans gestionnaire",20,60);
    g.drawLine(0,size().height,size().width,0);}
}