Solution de base                        

Solution de base pour faire fonctioner un bouton

     

L'application est représentée par les deux images ci-dessous. Quand on appuie sur le bouton trace, le disque rouge apparaît, quand on appuie sur le bouton efface, le disque disparaît. :

     

L'exemple utilise la classe Ardoise définie précédemment.

En ce qui concerne l'ajout du bouton et la répartition des sous-composants dans la fenêtre, on peut regarder les commentaires de l'exemple. Le containeur de la fenêtre contient deux JPanel, un sur fond gris pâle qui contient les deux boutons, et un sur fond jaune, qui est plus précisément de type Ardoise, dans lequel le disque est dessiné. Il n'aura pas été très heureux de mettre les boutons dans le même JPanel que celui où on fait le dessin.

Pour gérer les événements constitués par le clic sur l'un des boutons, on utilise l'interface ActionListener qui permet de définir un listener. On traite toujours les événements venant d'une action de l'utilisateur par l'intermédiaire de listeners. Il y a des listeners divers selon les types d'événements qui peuvent se produire. Nous verrons la plupart d'entre eux au cours de nos exemples. Les listeners sont toujours des instances d'une classe implémentant une interface de nom ...Listener, comme par exemple ici l'interface ActionListener ; plus précisément, les interfaces servant pour définir un listener hérite de l'interface EventListener.

L'interface ActionListener déclare une seule méthode : la méthode
    public void actionPerformed(ActionEvent);

La classe Boutons1 implémentant cette interface définit la méthode actionPerformed sans quoi elle devrait être déclarée abstraite.

La classe JButton possède la méthode :
    public void addActionListener(ActionListener l)

Dans notre programme, on utilise l'instruction :
    trace.addActionListener(this);.
On dit qu'on affecte le listener this au bouton trace. Puisque la classe Boutons1 implémente l'interface ActionListener, this est bien un ActionListener, ce qui correspond bien au prototype de la méthode addActionListener.

L'instruction :
    trace.addActionListener(this);.
signifie : quand il y a un clic sur le bouton trace, c'est this qui doit agir et, plus précisément, la méthode à exécuter est la méthode actionPerformed de this, c'est-à-dire de l'ActionListener fournie en paramètre à la méthode addActionListener du bouton trace.

L'ActionEvent figurant en paramètre de la méthode ActionPerformed est destinée à encapsuler des renseignements liés à l'événement. Dans notre exemple, ce paramètre s'appelle e et on peut connaître le composant qui est à l'origine de l'événement par e.getSource().

Lorsqu'on clique sur le bouton trace, le programme java est prévenu, il repère que l'événement a eu lieu sur le bouton trace, il constate qu'un listener (this) a été affecté au bouton trace ; il construit une instance de la classe java.awt.Event.ActionEvent contenant certains renseignements liés au clic (en particulier qu'il a eu lieu sur le bouton trace), il invoque la méthode actionPerformed de this en lui fournissant en paramètre l'instance de de la classe ActionEvent construite.

Le même principe s'applique à efface.

Les lignes en rouge dans le programme sont celles qui sont liées avec la gestion des événements (les clics sur les boutons).

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Boutons1 extends JPanel implements ActionListener {  
   private JButton trace = new JButton("trace");
   private JButton efface = new JButton("efface");
   private Ardoise  ardoise = new Ardoise();

   public Boutons1() {
      setLayout(new BorderLayout(5, 5));
      JPanel lesBoutons = new JPanel();
      lesBoutons.add(trace);
      lesBoutons.add(efface);
      add(lesBoutons, BorderLayout.NORTH);
      add(ardoise, BorderLayout.CENTER);
      trace.addActionListener(this);
      efface.addActionListener(this);
  }

   public void actionPerformed(ActionEvent e) {
      if (e.getSource() == trace) ardoise.setPossedeDisque(true);
      else if (e.getSource() == efface) ardoise.setPossedeDisque(false);
      ardoise.repaint();      
   }

   public static void main(String[] arg) {
      JFrame monCadre = new JFrame();
      monCadre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      monCadre.setLocation(200,200);
      monCadre.setContentPane(new Boutons1());
      monCadre.pack();
      monCadre.setVisible(true);
  }
}
Pour accéder au fichier Boutons1.java.
setLayout(new BorderLayout(5, 5)); : on demande ainsi que le composant dispose d'un gestionnaire de répartition du type BorderLayout. Ce gestionaire permet de demander de positionner des sous-composants au nord (NORTH), au sud (SOUTH), à l'ouest (WEST), à l'est (EAST) ou au centre (CENTER).Les deux chiffres 5 correspondent au fait qu'on demande d'espacer les sous-composants de 5 pixels en horizontal et 5 pixels en vertical.
lesBoutons.add(trace); : on demande ici d'ajouter le bouton trace au JPanel lesBoutons. Un composant de type JPanel possède par défaut un gestionnaire de répartition de la classe FlowLayout. Un tel gestionnaire dispose les sous-composants en ligne de la gauche vers la droite, au fur et à mesure de leurs insertions ; de plus le gestionnaire affecté par défaut à un composant de type JPanel centre l'ensemble des composants d'une ligne.

panneau.add(lesBoutons, BorderLayout.NORTH); : le panneau contenant les boutons doit être positionné au nord du composant.


© Irène Charon, Télécom ParisTech 2011