© Sofia ZAIDENBERGCNRS Mai 2007 1 Interfaces Graphiques Dessiner avec JAVA Contexte Graphique Rafraîchissement Java2D

  • Published on
    04-Apr-2015

  • View
    104

  • Download
    1

Embed Size (px)

Transcript

<ul><li> Page 1 </li> <li> Sofia ZAIDENBERGCNRS Mai 2007 1 Interfaces Graphiques Dessiner avec JAVA Contexte Graphique Rafrachissement Java2D </li> <li> Page 2 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 2 GUI Bibliographie The JFC Tutorial: A guide to constructing GUI Kathy Walrath, Mary Campione http://java.sun.com/docs/books/tutorial/uiswing Java Tutorial Specialized trails: Trail: 2D Graphics Deborah Adair, Jennifer Ball and Monica Pawlan http://java.sun.com/docs/books/tutorial/2d l Java 2D Graphics Jonathan Knudsen, Ed. O'Reilly l Java 2D API Graphics Vincent J. Hardy, Java Series, Prentice Hall </li> <li> Page 3 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 3 GUI Adaptateurs dvnements Dessin des segments de droite l Gestion des vnements souris Dplacement de la souris sur la zone de dessin met jour les coordonnes du curseur dans la barre dtat MOUSE_MOVED, MOUSE_DRAGGED Appuyer sur un bouton de la souris ( MOUSE_PRESSED ) dfinit le dbut dune droite Relcher le bouton de la souris ( MOUSE_RELEASED ) dfinit la fin de la droite type dvnement : MouseEvent source : zone de dessin interface dcoute : MouseListener rcepteur : zone de dessin MouseListener void mouseClicked(MouseEvent) void mouseEntered(MouseEvent) void mouseExited(MouseEvent) void mousePressed(MouseEvent) void mouseReleased(MouseEvent) Comme pour la fermeture de la fentre seule deux des mthodes de l interface nous intressent </li> <li> Page 4 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 4 GUI Adaptateurs dvnements Dessin des segments de droite import java.awt.*; import javax.swing.*; import java.awt.event.*; public class ZoneDessin extends JPanel implements MouseMotionListener { private BarreEtat be; public ZoneDessin(BarreEtat be) { setBackground(Color.white); setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); this.be = be; addMouseMotionListener(this); } public void mouseMoved(MouseEvent e) { be.afficheCoord(e.getX(),e.getY()); } public void mouseDragged(MouseEvent e) { be.afficheCoord(e.getX(),e.getY()); } } // ZoneGraphique addMouseListener(new GestionnaireClic(this)); public void initieDroite(int x, int y) { be.afficheMessage("Relacher pour dessiner la droite"); // on compltera ensuite } public void termineDroite(int x, int y) { be.afficheMessage("Cliquer pour initier une droite"); // on compltera ensuite } import java.awt.event.*; public class GestionnaireClic extends MouseAdapter { ZoneGraphique zone; public GestionnaireClic(ZoneGraphique z) { zone = z; } public void mousePressed(MouseEvent e) { zone.initieDroite(e.getX(),e.getY()); } public void mouseReleased(MouseEvent e) { zone.termineDroite(e.getX(),e.getY()); } Pour ne pas avoir dfinir des mthodes inutiles possibilit dutiliser un adaptateur dvnements : MouseAdapter </li> <li> Page 5 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 5 GUI Adaptateurs dvnements Dessin des segments de droite import java.awt.*; import javax.swing.*; import java.awt.event.*; public class ZoneDessin extends Jpanel implements MouseMotionListener { private BarreEtat be; public ZoneDessin(BarreEtat be) { setBackground(Color.white); setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); this.be = be; addMouseMotionListener(this); } public void initieDroite(int x, int y) { be.afficheMessage( Relacher pour dessiner la droite ); // on compltera ensuite } public void termineDroite(int x, int y) { be.afficheMessage( Cliquer pour initier une droite ); // on compltera ensuite }... } // ZoneGraphique new MouseAdapter() { public void mousePressed(MouseEvent e) { initieDroite(e.getX(),e.getY()); } public void mouseReleased(MouseEvent e) { termineDroite(e.getX(),e.getY()); } } addMouseListener( ); Avec une classe interne ( inner class ) anonyme ZoneDessin.this Linstance de la classe anonyme a implicitement accs linstance de la classe externe qui (c.--d. linstance) a provoqu sa cration : en consquence elle a accs aux membres de la classe externe </li> <li> Page 6 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 6 GUI Dessiner avec Java Dessin des segments de droite import java.awt.*; import javax.swing.*; import java.awt.event.*; public class ZoneDessin extends Jpanel implements MouseMotionListener { private BarreEtat be; public ZoneDessin(BarreEtat be) { setBackground(Color.white); setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); this.be = be; addMouseMotionListener(this); } public void initieDroite(int x, int y) { be.afficheMessage( Relacher pour dessiner la droite ); // on compltera ensuite } public void termineDroite(int x, int y) { be.afficheMessage( Cliquer pour initier une droite ); // on compltera ensuite }... } // ZoneGraphique new MouseAdapter() { public void mousePressed(MouseEvent e) { initieDroite(e.getX(),e.getY()); } public void mouseReleased(MouseEvent e) { termineDroite(e.getX(),e.getY()); } } addMouseListener( ); Comment dessiner avec Java ? // on compltera ensuite </li> <li> Page 7 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 7 GUI Contexte Graphique Ici le support du dessin est reprsent par une instance de la classe JPpanel avec java.awt dans la plupart des cas il sagit dune instance de la classe Canvas l Il faut des outils pour dessiner : l primitives gomtriques (droites, cercles, rectangles ) l gestion des attributs de trac (couleur du trait, couleur de remplissage, polices de caractres ) Ces outils sont reprsents en Java par la classe Graphics du package java.awt Classe abstraite : les instances de cette classe sont fournies la demande par le systme dexploitation qui, grce la machine virtuelle, instanciera une sous-classe de Graphics spcifique la plate-forme utilise Object Graphics The Graphics class is the abstract base class for all graphics contexts that allow an application to draw onto components that are realized on various devices, as well as onto off-screen images. A Graphics object encapsulates state information needed for the basic rendering operations that Java supports. mthodes de Graphics pour dessiner des formes </li> <li> Page 8 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 8 GUI Dessiner avec Java Dessin des segments de droite l Repre graphique Appuyer sur un bouton de la souris ( MOUSE_PRESSED ) dfinit le dbut dune droite Relcher le bouton de la souris ( MOUSE_RELEASED ) dfinit la fin de la droite type dvnement : MouseEvent Exprimes dans le repre de la source de lvnement : le JPanel X y x y ? ? ? ? x y Coordonnes position de la souris 150 50 250 110 </li> <li> Page 9 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 9 GUI Dessiner avec Java Dessin des segments de droite import java.awt.*; import javax.swing.*; import java.awt.event.*; public class ZoneDessin extends Jpanel implements MouseMotionListener { private BarreEtat be; public ZoneDessin(BarreEtat be) { setBackground(Color.white); setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); this.be = be; addMouseMotionListener(this); addMouseListener( new MouseAdapter() {... } ); } public void initieDroite(int x, int y) { be.afficheMessage( Relacher pour dessiner la droite ); } public void termineDroite(int x, int y) { be.afficheMessage( Cliquer pour initier une droite ); }... } // ZoneDessin int xInit, yInit; xInit = x; yInit = y; Lorsque le bouton de la souris est press : mmoriser le dbut dun nouveau segment Lorsque le bouton de la souris est relch : Graphics g = this.getGraphics(); 1) Rcuprer le contexte graphique associ au JPanel g.drawLine(xInit,yInit,x,y); 2) Utiliser lobjet Graphics pour effectuer le dessin </li> <li> Page 10 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 10 GUI Dessiner en Java rafraichissement du dessin l Problme de raffichage aprs que la fentre ait t masque, redimensionne 1 23 Zone non rafraichie l Application seule ne peut pas dcider du moment o elle doit tre rafrachie l Le systme ne prend pas en charge seul le rafrachissement l avertit uniquement lapplication quelle doit se redessiner (en lui indiquant quel est son rectangle invalide) l la charge de celle-ci de se redessiner GO </li> <li> Page 11 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 11 GUI Affichage d'un composant Quand un composant est-il affich ? l la demande du systme ( System triggered painting ) l la demande de lapplication ( Application triggered painting ) l quand le programme ou un composant Swing dtermine que le composant doit tre raffich l en interne dans les Swing (changement dun texte, dune couleur...) l dans votre propre programme en faisant une demande explicite de raffichage appel de la mthode repaint() du composant place une demande daffichage dans la file dattente des vnements le thread de gestion des vnements se chargera dappeler la mthode paint() l quand le composant est rendu visible pour la premire fois l quand le composant a t recouvert puis dcouvert appel de la mthode paint(Graphics g) du composant ne jamais appeler paint() directement, toujours utiliser repaint() </li> <li> Page 12 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 12 GUI Affichage d'un composant Que fait la mthode paint() ? 1) Le fond (background) (si opaque) 2) Affichage spcifique (custom painting) (si prsent) 3) Bordure (border) (si prsent) 4) Les fils (children) (si prsent) dessine le composant lui-mme dj implmente pour les composants standards (fentres, boutons, ) doit tre redfinie ( overriden ) pour crer vos propres composants Dessine les bordures ajoutes au composant (en utilisant setBorder ) paintComponent(Graphics g) paintBorder(Graphics g) paintChildren(Graphics g) Ne pas appeler directement cette mthode ni la redfinir. </li> <li> Page 13 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 13 GUI Affichage d'un composant l Un composant se dessine avant chacun des composants quil contient Laffichage dune interface Swing seffectue rcursivement en descendant la hirarchie des containers bouton 1 bouton 2 composant qui affiche du texte fentre contentPane panneau gauchepanneau droite composant textebouton1 bouton2 ordre daffichage </li> <li> Page 14 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 14 GUI Affichage d'un composant Pour rsumer l Chaque composant graphique possde une mthode qui dfinit comment il doit se dessiner public void paint(Graphics g) pour les composants awt public void paintComponent(Graphics g) pour les composants swings l videmment pour les composants standards (fentres, boutons, ) il est inutile de dfinir comment ils doivent safficher l une fentre affichera son cadre et son fond puis affichera tout les composants quelle contient l un conteneur affichera son fond puis affichera rcursivement tous les composants quil contient ll Mais ds que lapplication gre ses propres graphiques via un contexte graphique (objet Graphics ) elle devra se soucier de leur rafraichissement et redfinir paintComponent </li> <li> Page 15 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 15 GUI Dessiner en Java rafraichissement du dessin l Redessiner les segments de droite disparus l il faut stocker les informations pour afficher nouveau tous les segments dj dessins classes SegmentDroite et Dessin import java.awt.*; public class SegmentDroite { private int xInit, yInit, xFin, yFin; private Color couleur; public SegmentDroite(int xi, int yi, int xf, int yf, Color c) { xInit = xi; yInit = yi; xFin = xf; yFin = yf; couleur = c; } public void dessineToi(Graphics g) { g.setColor(couleur); g.drawLine(xInit, yInit,xFin,yFin); } import java.util.*; import java.awt.*; public class Dessin { private List lesDroites = new ArrayList(); public void ajouterDroite(SegmentDroite d) { lesDroites.add(d); } public void dessineToi(Graphics g) { for (Iterator it=lesDroites.iterator(); it.hasNext();) { SegmentDroite d = (SegmentDroite) it.next(); d.dessineToi(g); } public void efface() { lesDroites.clear(); } public void defaire() { if (! lesDroites.isEmpty()){ lesDroites.remove(lesDroites.size()-1); } } // Dessin Java 2 (1.4) </li> <li> Page 16 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 16 GUI import java.util.*; import java.awt.*; public class Dessin { private List lesDroites = new ArrayList(); public void ajouterDroite(SegmentDroite d) { lesDroites.add(d); } public void dessineToi(Graphics g) { for (Iterator it=lesDroites.iterator(); it.hasNext();) { SegmentDroite d = (SegmentDroite) it.next(); d.dessineToi(g); } public void efface() { lesDroites.clear(); } public void defaire() { if (! lesDroites.isEmpty()){ lesDroites.remove(lesDroites.size()-1); } } // Dessin Dessiner en Java rafraichissement du dessin l Redessiner les segments de droite disparus l il faut stocker les informations pour afficher nouveau tous les segments dj dessins classes SegmentDroite et Dessin import java.awt.*; public class SegmentDroite { private int xInit, yInit, xFin, yFin; private Color couleur; public SegmentDroite(int xi, int yi, int xf, int yf, Color c) { xInit = xi; yInit = yi; xFin = xf; yFin = yf; couleur = c; } public void dessineToi(Graphics g) { g.setColor(couleur); g.drawLine(xInit, yInit,xFin,yFin); } private List lesDroites = new ArrayList (); for (SegmetDroit d : lesDroites) { d.dessineToi(g); } Java 5 (1.5) </li> <li> Page 17 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 17 GUI Dessiner en Java rafraichissement du dessin l Redessiner les segments de droite disparus import java.awt.*; import javax.swing.*; import java.awt.event.*; public class ZoneDessin extends Jpanel implements MouseMotionListener { private BarreEtat be; private int xInit, yInit; public ZoneDessin(BarreEtat be) {... } public void initieDroite(int x, int y) { be.afficheMessage( Relacher pour dessiner la droite ); xInit = x; yInit =y; } public void termineDroite(int x, int y) { be.afficheMessage( Cliquer pour initier une droite ); Graphics g = this.getGraphics(); g.drawLine(xInit,yInit,x,y); }... } // ZoneDessin private Dessin dessin = new Dessin(); Rajout dun objet dessin pour mmoriser les segments dessins Mmorisation des nouveaux objets tracs SegmentDroite droite = new SegmentDroite(x,y,xInit,yInit,couleurCourante); dessin.ajouterDroite(droite); droite.dessineToi(g); public void paintComponent(Graphics g) { super.paintComponent(g); dessin.dessineToi(g); } Redfinition de la mthode paintComponent pour grer le raffichage Permet de dessiner larrire plan sinon laffichage du fond doit tre fait explicitement ou setOpaque(false) doit tre invoque pour informer le systme daffichage de Swing que les composants situs derrire peuvent tre visibles et doivent en consquence tre affichs </li> <li> Page 18 </li> <li> Sofia ZAIDENBERG CNRS Mai 2007 18 GUI Dessiner en Java rafraichissement du dessin type dvnement : ActionEvent source : les JButton interface dcoute : ActionListener Annule le dernier trac Efface toute la zone de dessin import java.awt.event.*; import java.awt.*; Import java.swing.*; public class BarreOutils extends JPanel { public BarreOutils(final ZoneDessin zd) {... JButton bDefaire = new JButton("Dfaire"); this.add(bDefaire); JButton bEffacer = new JButton("Tout effacer"); this.add(bEffacer);... bDefaire.addActionListener( ); bEffacer.addActionListener( );... } new ActionListener() { public void actionPerformed(ActionEvent e) { zd.efface(); } new ActionListener() { public void actionPerformed(Action...</li></ul>