MIM1
TD 5 de POOGL
Interface graphique : les composants et leur mise en place

Vincent BOUDET
Bureau 343 (84-70)
email vboudet@ens-lyon.fr

1 mars 2001

A   Un exemple introductif

Regardons l'exemple suivant :
import java.awt.*;
public class Fenetre extends Frame
{
    String message;

    public Fenetre(String titre, String message, int taille)
    {
        super(titre);
        this.message=message;
        setFont(new Font("Serif",Font.BOLD,taille));
    }

    public void paint(Graphics g)
    {
        g.drawString(message,50,70);
    }

    public static void main(String args[]) 
    {
        Fenetre f = new Fenetre("Ma premiere fenetre","Bonjour",24);
        f.setSize(250,100);
        f.setVisible(true);
    }
}
Quels sont les éléments importants à retenir de cet exemple ?

B   Un premier composant

Dans le paragraphe précédent, le méssage était écrit dans toute la fenêtre. Il est bien évident que l' on ne peut pas mobiliser tout l' espace de la fenêtre pour écrire des textes. Nous allons créeer un composant graphique et le placer dans la fenêtre.

import java.awt.*;
class STG extends TextArea
{
    STG(String text,
        int nblignes,
        int nbcolonnes,
        String police,
        int typepolice,
        int taillepolice)
    {
        super(text,nblignes,nbcolonnes, SCROLLBARS_NONE);
        // Fixe la police
        setFont(new Font(police, typepolice, taillepolice));
        // Pour empecher de modifier le texte
        setEditable(false);
    }
}
import java.awt.*;
class Composant1 extends Frame
{
    STG zonetexte;

    int nblignes = 5;
    int nbcolonnes = 20;
    
    public Composant1(String titre,
                      String message,
                      int taillepolice)
    {
        super(titre);
        zonetexte = new STG(message, 
                            nblignes, 
                            nbcolonnes, 
                            "Serif", 
                            Font.BOLD,
                            taillepolice);
        add(zonetexte, "North");
    }

    public static void main(String[] args)
    {
        Composant1 f;
        String titre = "Affichage dans une fenetre texte";
        String message = "Un composant\n TextArea permet\n"+
    "l'affichage\n de plusieurs lignes\n";
        int taillepolice=18;
        f = new Composant1(titre, message, taillepolice);
        f.pack();
        f.setVisible(true);
    }
}
Nous avons utilisé dans le programme précédent deux instructions importantes :

C   Gestionnaires de mise en page

Le rôle d' un gestionnaire de mise en page est de placer les composants graphiques dans la fenêtre, de les déplacer et/ou de les redimensionner. Il existe cinq gestionnaires de mise en page :

C.1   BorderLayout

Le gestionnaire attaché par défaut à une Frame est un BorderLayout. Sa caractéristique principale est de distinguer cinq zones dans la fenêtre : North, West, Center, East, South. Exemple:
import java.awt.*;
class Border extends Frame
{
   STG zonenord;
   STG zonesud;
   STG zoneest;
   STG zonecentre;
   STG zoneouest;
   
   
    int nblignes = 3;
    int nbcolonnes = 10;
    
    public Border(String titre,
                  int taillepolice)
     {
        super(titre);
 //Pour pr{\'e}ciser les marges entre les {\'e}l{\'e}ments :
 setLayout(new BorderLayout(5,10));
        zonenord = new STG("Nord",
                            nblignes, 
                            nbcolonnes, 
                            "Serif", 
                            Font.BOLD,
                            taillepolice);
        add(zonenord, "North");
        zonesud = new STG("Sud",
                          nblignes,
                          nbcolonnes,
                          "Serif",
                          Font.BOLD,
                          taillepolice);
        add(zonesud, "South");
        zoneest = new STG("Est",
                          nblignes,
                          nbcolonnes,
                          "Serif",
                          Font.BOLD,
                          taillepolice);
        add(zoneest, "East");
        zoneouest = new STG("Ouest",
                            nblignes,
                            nbcolonnes,
                            "Serif",
                            Font.BOLD,
                            taillepolice);
        add(zoneouest, "West");
        zonecentre = new STG("Centre",
                             nblignes,
                             nbcolonnes,
                             "Serif",
                             Font.BOLD,
                             taillepolice);
        add(zonecentre, "Center");
     }
   
   public static void main(String[] args)
     {
        Border f;
        String titre = "Utilisation d'un BorderLayout";
        int taillepolice=18;
        f = new Border(titre, taillepolice);
        f.pack();
        f.setVisible(true);
    }
}
Question C.1   Que se passe-t' il si on agrandit la fenêtre ?

C.2   FlowLayout

Ce gestionnaire place les composants de gauche à droite en commençant par le haut. Quand il n' y a plus de place sur une ligne on passe à la suivante. Le gestionnaire change la place des composants quand on redimensionne la fenêtre.

Question C.2   Effectuer les modifications suivantes à parit de Border.java pour obtenir Flow.java :

C.3   GridLayout

Le gestionnaire de mise en page GridLayout place les composants dans un tableau dont les cellules ont toutes la même taille. Le tableau de cellules occupe la totalité de la fenêtre et les composants s' étendent entièrement dans la cellule qui les abrite.

Question C.3   Reprenez l' exemple précédent le gestionnaire par setLayout(new GridLayout(3,2,5,10));

C.4   GridBagLayout

La mise en page la plus générale et la plus puissante se fait avec un GridBagLayout. C' est aussi la délicate. Comme la précédente, elle s' effectue dans un tableau de cellules, mais : L' établissement du gestionnaire se fait par :
GridBagLayout gbl = new GridBagLayout();
setLayout(gbl);
Il faut ensuite créer un objet de type GridBagConstraints dont les champs sont les contraintes à appliquer :
GridBagConstraint cons = new GridBagConstraint();
Voilà comment ajouté un composant :
cons.gridx=0;
cons.gridy=0;
cons.gridwidth=2;
cons.gridheight=1;
gbl.setConstraints(zonenord,cons);
add(zonenord);
Les instructions précédentes sont répétées pour les autres composants. Pour simplifier le programme, on a recourt à une méthode additionnelle :
void addComposantGridBag(GridBagLayout gb,
    GridBagConstraints cons,
    Component composant,
    int gridx,
    int gridy,
    int gridwidth,
    int gridheight)
{
  cons.gridx=gridx;
  cons.gridy=gridy;
  cons.gridwidth=gridwidth;
  cons.gridheight=gridheight;
  gb.setConstraints(composant,cons);
  add(composant);
}
Question C.4   Modifiez le programme précédent en placant les composants aux endroits suivants :
Il existe d' autres constraintes que les contraintes de placement. La liste vous est donnée dans une feuille jointe.
Question C.5   Amusez vous un peu avec tout ça...

C.5   Absence de gestionnaire

On peut aussi se passer de gestionnaire ( à ses risques et périls ) et tout placer à la main. Pour ce faire, il faut arrêter l' utilisation du gestionnaire par défaut : setLayout(null); et indiquer la position en pixels de chaque composant : zonenord.setLocation(50,50);

D   Composants graphiques

Nous venons de voir comment disposer des composants graphiques dans une fenêtre en n' ayant recours qu' à un seul type de composant, mais il en existe bien d' autres. Voici un bref aperç de ce qui existe :
TextAre :
Affichage de plusieurs lignes de texte
TextField :
Édition ou affichade d' une seule ligne de texte
Label :
Étiquettes ou légendes ne pouvant être éditées par l' utilisateur
Button :
Un bouton...
CheckBox :
Chaque case est individuelle, son état est indépendant de celui des autres. Dans le cas de boutons radio, les case sont groupées dans un CheckBoxGroup, il ne peut alors n' y avoir plus d' une case cochée.
Choice :
Listes déroulantes, le choix est unique.
List :
Listes de choix, le choix peut être multiple.
Menu, MenuItem, MenuBar :
Un objet de type Menu est un menu déroulant attaché à une barre de menu (MenuBar) et composé d' éléments (MenuItem)
Canvas :
Les canevas servent à dessiner, écrire des textes ou afficher des images
Pour de plus amples détails, je vous renvoie à la documentation en ligne.

E   Coneteneurs

Les conteneurs sont des composants graphiques qui possèdent la propriété de pouvoir recevoir d' autres composants (même des conteneurs). La classe Container est la classe mère de tous les conteneurs. Voici les principaux conteneurs :

E.1   Panel

Les panneaux sont les fenêtres de bas niveau les plus simples. Elles n' ont ni bordure ni titre. Elles doivent être attachées à un autre conteneur. Après avoir créé un panneau, on lui ajoute des composants graphiques de la même façon que s' il s' agissait d' un cadre, puis on lui l' ajoute lui-même à un autre conteneur. Son gestionnaire par défaut est FlowLayout.

E.2   Dialog

Les fenêtres de dialogues sont des fenêtres de haut niveau avec bordure et titre. Une fenêtre de dialogue est nécessairement attachée à une autre fenêtre qui est donnée en argument de son constructeur. Ces fenêtres peuvent être modales, c' est-à-dire qu' elles sont bloquantes. Tant qu' elles ne sont pas refermées, l' application qui les a créées est bloquée : setModal(True). Son gestionnaire par défaut est BorderLayout.

E.3   Frame

Les cadres sont des fenêtres de haut niveau avec bordure et titre, elles peuvent également posséder une barre de menu. Les applications graphiques possèdent toute une fenêtre mère de type Frame. Son gestionnaire par défaut est BorderLayout.

E.4   FileDialog

Les fenêtres de dialogue FileDialog servent à entrer le nom d' un fichier en navigant dans la hiérarchie des répertoires du système de fichier. Elles sont modales.

E.5   Applet

Les applet sont les fenêtres qui accueillent les programmes graphiques exécutés par un navigateur. On reviendra sur les applets plus tard.

F   Exercices

F.1   Barre de défilement

On veut créer une barre de défilement. Pour cela, on va créer une classe BarreDefile, sous-classe de Canvas avec les définitions suivantes :
largeur :
un entier indiquant la largeur de la barre,
pourcentage :
le pourcentage de la barre déjà affiché,
couleurFond :
la couleur de fond de la barre (de type Color),
couleurBarre:
la couleur de la barre (de type Color),
hauteur :
la hauteur de la barre (on peut la fixer à 15 par exemple),
BarreDefile :
le constructeur qui prend comme argument (largeur, couleurBarre, couleurFond),
afficher() :
méthode qui prend un entier x en paramètre, met à jour le pourcentage et affiche la barre mise à jour (voir la méthode update() des Canvas)(la couleur pourrait être changée quand le pourcentage atteint 100),
paint(Graphics g) :
affiche la barre, c' est cette méthode qui est appelé en fait par update() (nécessite setColor, setBackground et fillRect).
Question F.1   Créer la classe BarreDefile.java.
Question F.2   Créer une classe BarreDefileTest.java pour tester la classe précédente. Cette classe doit étendre une Frame et contenir plusieurs barres de défilement dont on fera varier le pourcentage afficher (penser à temporiser...)

F.2   Un visionneur d' image

Aller dans le répertoire /home/vboudet/Exemple/ et lancer java Xv. Nous allons réaliser cette petite application ensemble.
This document was translated from LATEX by HEVEA.