Les programmes précédents permettent de personnaliser l'aspect du composant, mais celui-ci n'est plus modifié une fois le composant mis en place. On peut aussi vouloir dessiner pendant l'exécution du programme.
Créer une nouvelle classe PanneauPerso3. Elle est presque analogue à PanneauPerso2 à ceci près qu'au lieu d'ouvrir un fichier image on crée une image vide . L'image (une BufferedImage) est copiée sur le panneau comme dans PanneauPerso2.
import java.awt.*; import java.awt.image.*; import javax.swing.*; public class PanneauPerso3 extends JPanel{ BufferedImage dessin; PanneauPerso3(){ super(); setOpaque(true); setPreferredSize(new Dimension(500,500)); setBackground(Color.DARK_GRAY); dessin=new BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB); } public void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(dessin,0,0,null); } }
L'image est créée en appelant le constructeur de la classe BufferedImage dans la ligne dessin=new BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB); Les deux premiers paramètres sont la largeur et la hauteur de l'image, le troisième est une constante définie dans la classe BufferedImage et qui indique le type d'image. Celui utilisé ici convient bien pour une image en couleurs sous Windows.
Pour pouvoir dessiner sur l'image, il faut récupérer le Graphics2D associé à cette image, puis dessiner dessus. Ensuite on appelle la méthode repaint() pour le PanneauPerso3 : cet appel déclenche l'exécution de paintComponent, ce qui copie l'image sur le panneau (on ne doit pas appeler directement paintComponent).
N'oubliez pas de changer "PanneauPerso2" en "PanneauPerso3" dans la classe Fenetre, pour signaler qu'il faut utiliser ce nouveau modèle de panneau personnalisé.
Par exemple on peut écrire dans Appel du code qui dessine sur l'image (cela nécessite d'importer dans Appel la bibliothèque java.awt qui contient tout ce qu'il faut pour dessiner).
Dans Appel, après la création de la fenetre une_fenetre, on ajoute l'instruction :
Graphics2D g=une_fenetre.panneau.dessin.createGraphics();qui permet de récupérer le Graphics2D g sur lequel on va dessiner.
Explications sur cette syntaxe :
une_fenetre.panneau.dessin désigne : l'objet "dessin" contenu dans l'objet "panneau" contenu dans l'objet "une_fenetre"
La classe Appel ne connaît en effet pas d'objet appelé dessin ou panneau, mais elle connaît "une_fenetre".
"une_fenetre" est une instance de la classe "Fenetre", dans laquelle on a défini l'instance "panneau" de la classe PanneauPerso3, donc "une_fenetre" connaît "panneau".
"dessin" est créé par le constructeur de la classe PanneauPerso3 au moment de la construction de l'instance "panneau", donc "panneau" connaît "dessin".
une_fenetre.panneau.dessin.createGraphics() permet donc d'appeler depuis "Appel" la méthode createGraphics() de la classe BufferedImage, dont "dessin" est une instance : "dessin" connaît donc la méthode createGraphics().
L'instruction "indique le chemin" que doit suivre le compilateur pour trouver la méthode, en partant de la classe Appel.
On écrit ensuite les instructions de dessin , par exemple :
g.setColor(new Color(60,80,128)); g.fillRect(0,0,une_fenetre.panneau.dessin.getWidth(),une_fenetre.panneau.dessin.getHeight()); int rouge, vert, bleu, x1,y1,x2,y2; for (int i=0;i<100;i++){ rouge=(int)(127+128*Math.random()); bleu=(int)(127+128*Math.random()); vert=(int)(127+128*Math.random()); x1=(int)(500*Math.random()); y1=(int)(500*Math.random()); x2=(int)(500*Math.random()); y2=(int)(500*Math.random()); g.setColor(new Color(rouge, vert,bleu)); g.drawRect(x1, y1, x2-x1, y2-y1);qui permet de dessiner un fond bleu et cent rectangles de couleur, taille et position aléatoires.
Et enfin
une_fenetre.panneau.repaint();pour être sûr que le contenu du panneau est mis à jour.
Comme d'habitude, on visualise le résultat en exécutant Appel.