Ardoise : une instance de JPanel

     

alt : l'applet n'est pas visible par votre navigateur (dans le menu Outils, Modules complémentaires, activer le plugin Java(TM) Platform SE 6 U32 6.0.320.5 s'il est désactivé) , vous pouvez exécuter : VoirFenetre.jar

On définit ici une classe pour modéliser un panneau dans lequel s'affiche un disque si la variable possedeDisque de la classe Ardoise vaut true.
De façon à voir une instance de Ardoise, on définit aussi la classe VoirFenetre ; la méthode main de cette classe construit une instance de la classe JFrame qui a pour containeur une instance de la classe Ardoise.


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

public class Ardoise extends JPanel {
static final long serialVersionUID = 1;
private boolean possedeDisque = true;

public Ardoise() {
setBackground(Color.YELLOW);
setPreferredSize(new Dimension(200, 150));
}

public void setPossedeDisque(boolean possedeDisque) {
this.possedeDisque = possedeDisque;
}

public void dessiner(Graphics g) {
g.setColor(Color.RED);
g.fillOval(60, 35, 80, 80);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (possedeDisque) dessiner(g);
}
}

class VoirArdoise {
public static void main(String[] arg) {
Frame cadre = new javax.swing.JFrame("Un disque");
cadre.setContentPane(new Ardoise());
cadre.setLocation(400, 300);
cadre.pack();
cadre.setVisible(true);
cadre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Pour accéder au fichier Ardoise.java.
Et pour l'applet : VoirFenetreApplet.java.

static final long serialVersionUID = 1; : cette instruction n'est pas particulière aux interfaces graphiques mais tient au fait que la classe JPanel étend l'interface java.io.Serialisable et que notre classe sera donc sérialisable ; ce n'est pas nécessaire de s'occuper devcela pour l'instant, si vous ne mettez pas cette instruction vous aurez un avertissement (Warning) du compilateur.


public void paintComponent(Graphics g) : on redéfinit ici la méthode paintComponent de la classe JPanel.
De temps à autre, un composant à besoin d'être dessiné ; c'est le cas par exemple à l'ouverture de la fenêtre ou quand la fenêtre est momentanément recouverte puis découverte ou bien quand la fenêtre est mise sous forme d'icône et réouverte, ou bien parce que le programme demande directement de repeindre le composant. Dans tous les cas, ce sera la méthode repaint (sans paramètre) définie dans les classes de tous les composants graphiques qui sera invoqué. La méthode repaint d'un composant effectue les tracés "en dur" (comme par exemple un bord, ou un relief), elle invoque la méthode paintComponent du composant et elle appelle les méthodes repaint de ses sous-composants.
Il faut redéfinir la méthode paintComponent dans tout composant où on souhaite tracer des éléments particuliers. La méthode paintComponent définie dans JPanel "peint" le fond du composant dans la couleur d'arrière-plan (background) ; si on veut ajouter des tracés spécifiques, il faut redéfinir la méthode paintComponent comme on le fait ici ; par le mécanisme de la liaison dynamique, c'est la méthode redéfinie dans la classe Ardoise qui sera exécutée si l'instance concernée est d'un type Ardoise qui étend JPanel.
Si on veut demander à repeindre le contenu d'un JPanel, ou d'un composant quelconque, on n'appelle jamais directement la méthode paintComponent ; il convient de toujours d'invoquer repaint() du composant qu'on veut redessiner.
super.paintComponent(g); : il est toujours ainsi nécessaire quand on redéfinit la méthode paintComponent de faire appel au début de la méthode à super.paintComponent(g); ; la méthode paintComponent de la superclasse pour qu'elle effectue son propre travail et en particulier le coloriage du fond.
dessiner(g); : lorsque la méthode repaint invoque la méthode paintComponent, elle lui passe en paramètre une instance de la classe Graphics qui n'est pas destiné au composant concerné mais à ce qu'on appelle une image arrière, image en mémoire ; la méthode paintComponent trace ainsi le dessin dans l'image arrière. Quand l'image arrière est terminée (c'est-à-dire quand la méthode paintComponent est terminée), l'image arrière est dessiné "d'un seul coup" dans le composant. Il donc nécessaire d'utiliser le paramètre de type Graphics figurant dans l'en-tête de paintComponent pour effecter les différents tracés; c'est ce qui est fait dans notre exemple quand on écrit dessiner(g).
g.setColor(Color.RED); : on choisit la couleur rouge pour le crayon, c'est-à-dire pour g. Le dessin sera fait en rouge.
g.fillOval(60, 35, 80, 80); : on demande ici à tracer un ovale plein ; les deux premiers paramètres donnent l'abscisse et l'ordonnée du coin supérieur gauche du rectangle englobant l'ovale par rapport au coin supérieur gauche du composant dans lequel l'ovale est dessiné, l'axe vertical étant dirigé vers le bas ; les deux derniers paramètres donnent la longueur des axes horizontal et vertical de l'ovale ; l'unité est le pixel. Le schéma suivant correspond à g.drawOval(50, 20, 100, 100) pour un ovale non plein :

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