Utilisation de classes internes                        

Utilisation de classes internes

     

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. :

     

On utilise toujours ici la classe Ardoise.

Cette solution présente l'avantage de décrire le rôle de chaque bouton à l'endroit où figure l'instruction addActionListener appliquée au bouton concerné.

On a la possibilité, avec certaines règles, d'inclure une classe dans une autre classe. Nous utilisons ici cette possibilité.

Introduisons une nouvelle notion. Une classe qui a pour fonctionnalité principale de fournir les méthodes de un ou plusieurs listeners(s) est appelée une classe déléguée, ou encore un délégué. Le nom vient du fait que l'on délègue à cette classe une partie du travail que l'on souhaite effectuer dans une application, partie souvent centrale. On dit aussi quelquefois que c'est un contrôleur de l'application ; ce dernier qualificatif intervient quand on met en place le modèle "Modèle-Vue-Controleur" (MVC) : le modèle est alors le cœur de l'application, indépendant de la représentation graphique, la vue est la représentation graphique, le contrôleur permet de transmettre les événements provenant de l'utilisateur au modèle.

Il est nécessaire de spécifier pour chaque bouton la conduite à tenir en cas de clic. Ici, on définit une classe déléguée pour chaque bouton, et on le fait avec des classes internes pour rapprocher le plus possible le délégué de l'objet qui en a besoin. On utilise deux façons différentes.

Pour le bouton trace, on définit une classe déléguée interne à la classe Boutons3, la classe DelegueTrace, comme s'il s'agissait d'une classe non interne. Les autres champs de la classe Boutons3 (ici, il n'y en a pas...) sont visibles des méthodes définies dans les classes internes ; les variables locales de la méthode contenant la classe interne (ici le constructeur de la classe Boutons3) sont visibles des méthodes définies dans les classes internes à condition d'être déclarées final pour que ce soit des constantes. On utilise alors la classe DelegueTrace dans l'instruction : :
    trace.addActionListener(new DelegueTrace());
Un clic sur le bouton trace conduira à utiliser la méthode actionPerformed de la classe DelegueTrace.

Pour le bouton efface, on effectue un raccourci de la solution précédente en utilisant de qu'on appelle une classe anonyme. La description de la classe se fait simultanément avec son instanciation, avec la syntaxe visible sur l'exemple.

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 Boutons3 extends JFrame {
    public Boutons3() { 
	final Ardoise ardoise = new Ardoise(); 
	JButton trace = new JButton("trace");
	JButton efface = new JButton("efface");
	JPanel lesBoutons = new JPanel();

	lesBoutons.add(trace);
	lesBoutons.add(efface);
	setLayout(new BorderLayout(5, 5));
	add(lesBoutons, BorderLayout.NORTH);
	add(ardoise, BorderLayout.CENTER);
	
	class DelegueTrace implements ActionListener {
	    public void actionPerformed(ActionEvent e) {
		ardoise.setPossedeDisque(true);	  
		ardoise.repaint();
	    }
	}
	
	trace.addActionListener(new DelegueTrace());
	
	efface.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e) {
		    ardoise.setPossedeDisque(false);	  	  
		    ardoise.repaint();
		}
	    });

	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	setLocation(200,200);
	pack();
	setVisible(true);
    }
}

class EssaiBoutons3 {
   public static void main(String[] arg) {
      new Boutons3());
   }
}
Pour accéder au fichier Boutons3.java.
final Ardoise ardoise : il faut ici mettre le mot final pour que ardoise soit une constante ; sinon, il serait interdit d'utiliser ardoise dans les classes internes.

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