7/ Gérer une interface graphique et la programmation événementielle


Les packages pour créer des interfaces graphiques
Les conteneurs
Les gestionnaires de placement
Les composants graphiques
Schéma d'une fenêtre
La gestion des événements
Exemple de code
Les interfaces écouteurs d'événements AWT
Les interfaces écouteurs d'événements swing

Deux packages permettent de gérer les interfaces graphiques : AWT et SWING (intégré à partir de la version 1.2).
AWT utilise des composants lourds, c'est à dire utilisant les ressources du système d'exploitation, alors que Swing utilise des composants dits légers n'utilisant pas ces ressources. Swing est plus robuste que l'AWT, plus portable, et plus facile à utiliser.
Swing ne remplace pas complétement AWT mais fournit des composants d'interface plus performants.

Chaque composant AWT a son équivalent Swing dans le package javax.swing. Nous nous intéresserons surtout aux possibilités développées dans le package swing. (En cours de développement)

Les composants d'une interface utilisateurs sont placés dans des conteneurs. Chaque objet Conteneur utilise un gestionnaire de placement (layout) pour contrôler la taille de l'écran et la disposition des objets qu'il contient.

 
Objets
Fonction
Container 
    Window
        Dialog
            JDialog
        Frame
           JFrame
    Panel
        Applet 
           JApplet
Les conteneurs sont des éléments graphiques composés d'autres éléments graphiques. 
Les objets Applet héritent de Panel
Les fenêtres (Dialog et Frame héritent de Window) permettent de créer des  fenêtres ou des boites de dialogue. La gestion des menus et de la barre de titre font également partie de ce type d'objets. 
Ces objets ont un LayoutManager qui leur est associé et qui définit la manière dont sont répartis les objets qu'ils accueillent. 

Pour ajouter un Component dans un Container, vous pouvez utiliser des méthodes d'ajout.

Les composants standards d'IHM de swing dérivent aussi de la classe Container. 

Layouts ou gestionnaires de placement 
    BorderLayout
    CardLayout 
    GridLayout 
    GridBadLayout 
    FlowLayout
Fournissent le service d'organisation et d'arrangement des objets à l'écran. Ils sont insérés dans des objets  Conteneur. 
Le gestionnaire par défaut des objets conteneurs est le FlowLayout.
Les composants graphiques 
    Button
    Canvas
    CheckBox
    Choice
    Label
    JButton 
    JLabel
    JList
    List
    TextArea
    TextComponent
    TextField
Ils regroupent les objets traditionnels présents dans une interface graphique. 
Une fenêtre peut donc être construite selon le principe suivant :

La gestion des événements :

Les événements sont ce qui est renvoyé par les systèmes d'exploitation qui supportent les interfaces graphiques aux programmes lorsque des pressions sur les touches du clavier ou sur les boutons de la souris sont effectuées.

A partir de la version 1.1 du jdk les événements sont gérés par AWT selon le principe suivant :

Des objets sources d'événements (bouton, barre de défilement, ...) transmettent les événements à des objets écouteurs d'événements.

En général et par convention, l'écouteur d'événement d'un composant d'interface, est souvent le conteneur de ce composant.
 
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

class ButtonPanel extends JPanel 
   implements ActionListener    // interface écouteur d'événements
{ private JButton Boutonjaune;
   private JButton BoutonBleu;
   private JButton BoutonRouge; 

   public ButtonPanel() // constructeur de la classe ButtonPanel
   {  Boutonjaune = new JButton("Jaune");
      BoutonBleu = new JButton("Bleu");
      BoutonRouge = new JButton("Rouge");
      // Insertion des trois boutons dans l'objet ButtonPanel
      add(Boutonjaune);
      add(BoutonBleu);
      add(BoutonRouge);
      // Les sources d'événements sont déclarées à l'écouteur
      Boutonjaune.addActionListener(this); 
      BoutonBleu.addActionListener(this); 
      BoutonRouge.addActionListener(this); 
   }

   public void actionPerformed(ActionEvent evt)
   // Permet de traiter l'événement en fonction de l'objet source
   {  Object source = evt.getSource();
      Color color = getBackground();
      if (source == Boutonjaune) color = Color.yellow;
      else if (source == BoutonBleu) color = Color.blue;
      else if (source == BoutonRouge) color = Color.red;
      setBackground(color);
      repaint();
   }
}

class ButtonFrame extends JFrame
{  public ButtonFrame()
   {  setTitle("ButtonTest");
      setSize(300, 200);
      addWindowListener(new WindowAdapter()
         {  public void windowClosing(WindowEvent e)
            {  System.exit(0);
            }
         } );

      Container contentPane = getContentPane();
      contentPane.add(new ButtonPanel());
   }
}

public class ButtonTest
{  public static void main(String[] args)
   {  JFrame frame = new ButtonFrame();
      frame.show(); 
   }
}

Dans la version 1.0x de java, quand un l'utilisateur agit sur un composant, un objet Event se crée. Le système de gestion d'événement transmet l'objet Event vers le haut de la hiérarchie des composants, jusqu'à ce qu'un objet réponde à l'événement grâce aux méthodes action() et handleEvent().

Les interfaces écouteurs d'évenements :

Une classe qui désire recevoir des événements doit implémenter une interface écouteur. Elle se recense auprès de la source d'événement, puis elle reçoit les événements souhaités et les traite grâce aux méthodes de l'interface écouteur.

Il y a onze interfaces écouteurs dans le package java.awt.event :

Certaines interfaces écouteurs sont accompagnées d'adaptateurs qui implémentent toutes les méthodes de l'interface afin qu'elles n'accomplissent aucune action. En effet, toutes les méthodes d'une interface ne sont pas forcément utilisées, l'adaptateur évite d'avoir à les citer dans le programme (voir exemple). Ces adaptateurs sont les suivants : Les interfaces écouteurs du package java.swing.event :