Un exemple composé

sommaire      un panneau    

Une interface définit un contrat que certaines classes pourront s'engager à respecter.

Une interface est définie "parallèlement" aux classes.
Une interface contient :

La figureci-dessous résume les liens entre les différentes classes de l’exemple. On y lit que la classe CercleGraphique étend la classe Cercle, que la classe CarreGraphique étend la classe Carre, et que les classes CercleGraphique et CarreGraphique implémentent l’interface Tracable.

Dans ce shéma :

schéma de relations entre les classes et les interfaces de l'exemple


L’interface Tracable

L’interface Tracable (lire Traçable) définie ci-dessous comporte la constante entière DIM_MAX et le prototype de la méthode dessine. Une classe qui implémentera l’interface Tracable possèdera   la constante DIM_MAX et est dans l’obligation de définir la méthode dessiner, à moins d’être abstraite (notion vue plus tard).
package tracable;
public interface Tracable {
    public static final int DIM_MAX = 500;
    public void dessiner(java.awt.Graphics g);
}

Une classe pour définir un Cercle

La classe Cercle nous servira de superclasse. On peut y remarquer l’utilisation de la constante statique PI issue de la classe java.lang.Math.

package tracable;
public class Cercle {
    int rayon;
    public Cercle(int rayon) {
        this.rayon = rayon;
    }

    public int getRayon() {
        return rayon;
    }

   double circonference() {
        return 2 * Math.PI * rayon;
   
}
}

Une classe qui étend Cercle et implémente l'interface Tracable

Nous allons voir maintenant une classe, la classe CercleGraphique, qui simultanément étend la classe Cercle et implémente l’interface Tracable. Cette classe modélise un cercle que l’on peut dessiner dans un composant graphique ; le cercle n’est dessiné que si son rayon ne dépasse pas la valeur de la constante DIM_MAX de l’interface Tracable. Pour que le cercle puisse être tracé, il ne faut plus uniquement connaître son rayon mais aussi connaître la position souhaitée dans le composant où il sera tracé et sa couleur. Puisque la classe CercleGraphique implémente l’interface Tracable, elle doit définir la méthode dessiner annoncée dans Tracable et munir cette méthode du modificateur de visibilité public. C’est ce qui est fait ici. 
package tracable;
public class CercleGraphique extends Cercle implements Tracable {
    private int x, y;                   // x et y : coordonnees du centre du cercle
    private java.awt.Color couleur;     // couleur : la couleur du cercle

    public CercleGraphique(int rayon, int x, int y, java.awt.Color couleur) {
        super(rayon);
        this.x = x;
        this.y = y;
        this.couleur = couleur;
    }

    public void dessiner(java.awt.Graphics g) {
        int rayon = getRayon();
        if (rayon < DIM_MAX) {
            g.setColor(couleur);
            g.drawOval(x - rayon, y - rayon, 2*rayon, 2*rayon);
        }
    }
}

Une classe pour définir un carré

La classe Carre ressemble à la classe Cercle. Elle sera étendue en une classe implémentant l’interface Tracable et permettra plus loin d’avoir deux classes différentes implémentant Tracable.

package tracable;

public class Carre {
    private int cote;

    public Carre(int cote) {
        this.cote = cote;
    }

    public int getCote() {
        return cote;
    }

    public int surface() {
        return cote*cote;
    }
}

Une classe qui étend Carre et implémente Tracable

La classe CarreGraphique ressemble à la classe CercleGraphique.
package tracable;

import java.awt.Color;
import java.awt.Graphics;

public class CarreGraphique extends Carre implements Tracable {
private int x, y; //coordonnees du centre
private Color couleur = Color.BLACK; // couleur par défaut du carre

public CarreGraphique(int cote, int x, int y) {
super(cote);
this.x = x;
this.y = y;
}

public CarreGraphique(int cote, int x, int y, Color couleur) {
this(cote, x, y);
this.couleur = couleur;
}

public void dessiner(Graphics g) {
int cote = getCote();
if (cote < DIM_MAX) {
g.setColor(couleur);
g.drawRect(x - cote/2, y - cote/2, cote, cote);
}
}
}

Un tableau de Tracable

On peut ranger un objet de type CercleGraphique ou bien CarreGraphique dans une variable destinée à recevoir un objet de type Tracable. Cela permet entre autres de définir un tableau de Tracable. C’est ce qu’on fait dans l’exemple suivant : on construit un tableau de Tracable pour les différents ingrédients d’un dessin qu’on souhaite obtenir ; la méthode dessiner, spécifiée dans Tracable, est appliquée sur chacune des instances du tableau. On obtient à l’exécution la fenêtre représentée par la figure ci-dessous.
la tête

Nous n’expliquons que peu ce qui concerne les interfaces graphiques. Ce sujet sera traité plus loin.

package tracable;

import java.awt.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JPanel;
import javax.swing.JFrame;

public class EssaiTracable extends JPanel {
    Tracable[] desFormes = new Tracable[5];

    public EssaiTracable() {
        setPreferredSize(new Dimension(200, 200));
        desFormes[0] = new CercleGraphique(75, 100, 100, Color.BLACK);
        desFormes[1] = new CercleGraphique(10, 65, 75, Color.BLUE);
        desFormes[2] = new CercleGraphique(10, 135, 75, Color.BLUE);
        desFormes[3] = new CarreGraphique(10, 100, 110, Color.MAGENTA);
        desFormes[4] = new CarreGraphique(15, 100, 150, Color.RED);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Tracable forme : desFormes) forme.dessiner(g);
    }

    public static void main(String[] arg) {
        JFrame monDessin = new JFrame();

        monDessin.setContentPane(new EssaiTracable());
        monDessin.pack();
        monDessin.setVisible(true);
    }
}


public static final : ces modificateurs sont facultatifs ; qu’ils figurent ou non, l’attribut DIM_MAX est traité par le compilateur comme étant une constante (final) statique (static).
public : ce modificateur est facultatif ; qu’il figure ou non, cette déclaration de méthode est traitée comme étant publique par le compilateur.
java.awt.Graphics : la classe java.awt.Graphics modélise ce qu’on appelle un contexte graphique et définit un ensemble de fonctionnalités permettant d’effectuer des tracés dans un composant graphique donné. Pour dessiner dans un composant graphique, on passe nécessairement par une instance de Graphics ; cette instance est liée au composant et ne servira qu’à faire des tracés dans ce composant. Entre autres, une instance de Graphics possède des méthodes destinées à tracer des lignes, des cercles, permet d’écrire des chaînes de caractères, etc. ; on peut définir la couleur des traits et la police de caractères. On reverra cela en détails.

java.awt.Color : on utilise ici une classe du paquetage java.awt, classe qui contient ce qui est nécessaire pour disposer de couleurs. On nomme la classe par son nom complet car nous n’avons pas choisi de mettre en début du fichier une des instructions : import java.awt.*; import java.awt.Color; qui aurait permis d’utiliser le nom court Color de cette classe.


DIM_MAX : la constante DIM_MAX définie dans Tracable est connue dans CercleGraphique qui implémente Tracable.


g.setColor(couleur); : on donne ainsi à l’objet Graphics g la couleur souhaitée pour le tracé du cercle.


g.drawOval(x - rayon, y - rayon, 2*rayon, 2*rayon); : cette instruction provoque le tracé du cercle (comme cas particulier d’un ovale) dans le composant graphique du contexte graphique g. Les paramètres sont l’abscisse et l’ordonnée du coin supérieur gauche du rectangle circonscrit à l’ovale (l’origine des coordonnées étant le coin supérieur gauche du composant), la largeur et la hauteur de cet ovale.


this(cote, x, y) : on fait ainsi appel au constructeur de la classe CarreGraphique ayant trois paramètres de type int.
g.drawRect(x - cote/2, y - cote/2, cote, cote); : cette méthode trace un rectangle dans le composant graphique relatif à g ; les paramètres donnent l’abscisse et l’ordonnée du coin supérieur gauche, la hauteur et la largeur du rectangle.

JPanel : la classe javax.swing.JPanel fournit un composant graphique qui peut servir à contenir d’autres composants et pour effectuer des tracés.

public void paintComponent(Graphics g) : cette méthode sera automatiquement invoquée quand le composant apparaît et chaque fois qu’il a besoin d’être redessiné (par exemple, s’il a été momentanément recouvert).

forme.dessiner(g); : on peut utiliser la méthode dessiner sur toute instance de type Tracable (c’est-à-dire d’une classe qui implémente l’interface Tracable), la méthode exécutée varie selon la classe de l’objet concernée.

JFrame : la classe javax.swing.JFrame modélise une fenêtre principale d’application, pouvant avoir un titre et une barre de menus, changer de taille, se mettre sous forme d’icone, etc.

 monDessin.setContentPane(new EssaiTracable()); : l’intérieur de la fenêtre monDessin sera une instance de la classe EssaiTracable.

monDessin.pack(); : cette instruction permet de dimensionner la fenêtre en fonction de ce qu’elle contient. 

monDessin.setVisible(true); : cette instruction est indispensable pour que la fenêtre soit visible.

© Irène Charon Télécom ParisTech 2012