Interfaces Graphiques

Slides:



Advertisements
Présentations similaires
LES NOMBRES PREMIERS ET COMPOSÉS
Advertisements

1 Georgeta BĂDĂU CRÉATION ET GESTION DUN BLOG AVEC LA PLATE-FORME LEWEBPEDAGOGIQUE.COM Séance no.6.
Portée des variables VBA & Excel
Gestion des événements (suite)
Introduction à la Programmation Orientée Objet Retour sur les principaux concepts SI3 MAM3 Hydro Nathan Cohen
Cours MIAGE « Architectures Orientées Services » Henry Boccon-Gibod 1 Architectures Orientées Services Composants de Service Exemple pratique de développement.
Page 1 Les applets Jacques Lonchamp. Page 2 Présentation Une applet est téléchargée à partir dune machine distante qui fournit le code. Ce chargement.
(Classes prédéfinies – API Java)
Voisin-Polian : Introduction à Java 1 Introduction à Java - AWT - Frédéric VOISIN – Nicole POLIAN FIIFO - « Remise à Niveau »
Partiel : le sujet Un graphe non-orienté :
contrat Creative Commons Paternité-Pas d'Utilisation Commerciale- Partage des Conditions Initiales à l'Identique.
Lexique des manœuvres de base pour utiliser à PowerPoint
LICENCE MIAGE Introduction Programmation Orientée Objet JAVA philippe
JAV - TD 6 Structures de données JAVA
Copyright © 2001 Laurent Deruelle1 LE GRAPHISME AVEC JAVA 2D Laurent Deruelle
ESIEE Paris © Denis BUREAU I N Initiation à la programmation avec le langage Java.
User management pour les entreprises et les organisations Auteur / section: Gestion des accès.
Programmation par Objets et Java
Mr: Lamloum Med LES NOMBRES PREMIERS ET COMPOSÉS Mr: Lamloum Med.
Par Fabrice Pasquier Cours IV
44 Contrôle du déroulement du programme. 4-2 Objectifs A la fin de ce cours, vous serez capables de : Utiliser les constructions de prise de décision.
420-B63 Programmation Web Avancée Auteur : Frédéric Thériault 1.
Faculté I&C, Claude Petitpierre, André Maurer 1 Java.
Écouteurs de click d'une fenêtre
Python Interfaces graphiques
Langage Oriente Objet Cours 4.
1 Guide de lenseignant-concepteur Vincent Riff 27 mai 2003.
© 2007 P. Van Roy. All rights reserved. FSAB1402: Informatique 2 Le Langage Java et les Exceptions Peter Van Roy Département dIngénierie Informatique,
77 Utilisation des classes (suite). 7-2 Objectifs A la fin de ce cours, vous serez capables de : Définir des méthodes surchargées dans une classe Fournir.
Chapitre 21 Collections Partie I Introduction Une collection : est un objet qui regroupe multiple éléments dans une unité. Une collection est.
1 Objectifs de ce cours (I21) Cours JAVA (I21) -Licence 1 Semestre 2 / Y.Laborde Résumé du cours précédent.
F Copyright © Oracle Corporation, Tous droits réservés. Créer des programmes avec Procedure Builder.
LES NOMBRES PREMIERS ET COMPOSÉS
Graphical User Interface (GUI)
Master 1 SIGLIS Java Lecteur Stéphane Tallard Chapitre 5 – Héritage, Interfaces et Listes génériques.
Gestion des événements liés à la fenêtre et aux périphériques dentrée.
Graphical User Interface
2 TP avec l ’aide d ’un modeleur 3D :
DESS CCI POO-JAVA TD n°7 exercice n°1
Rappels Java.
1. 2 PLAN DE LA PRÉSENTATION - SECTION 1 : Code HTML - SECTION 2.1. : CSS (Méthode 1) - SECTION 2.2. : CSS (Méthode 2) - SECTION 3 : JavaScript - SECTION.
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
Formation Développeur Java Applet et interfaces graphiques avec AWT
COURS DE PROGRAMMATION ORIENTEE OBJET :
99 Réutilisation du code grâce à l'héritage. 9-2 Objectifs À la fin de ce cours, vous serez capables de : Définir l'héritage Utiliser l'héritage pour.
Équipe 2626 Octobre 2011 Jean Lavoie ing. M.Sc.A.
Mise en forme en Mathématiques

Elaboré par M. NUTH Sothan 1. 2 Soit x, y et z des coordonnées cartésiennes à 3 dimension. G un ensemble de points dans le plan (u, v). Déf. : On appelle.
Bienvenue sur CAUTIONET l'outil On Line de gestion de caution
Biologie – Biochimie - Chimie
Création et présentation d’un tableau avec Word 2007
Objectifs À la fin de ce cours, vous serez capables de :
Cour : Microsoft excel FACULTE DES SCIENCES AGADIR
LES PILES ET FILES.
LIFI-Java 2004 Séance du Mercredi 22 sept. Cours 3.
22 Visual Studio Tools et Office 2010 Thomas LEBRUN Architecte Access It Sebastien BOVO Application Dev Consultant Microsoft France
1 Formation à l’usage éco-performant de votre pc 1 ère Partie.
Introduction à l’informatique en gestion 1 Plan de la leçon Compagnon office Sections et Mise en page En-têtes et pieds de page Notes de bas.
11/04/ L'héritage Cours 7 Cours 7.
Variables et accès en Java. Déclaration des variables final transient static private Printer hp; transient => ne doivent pas être sérialisées volatile.
Cours 91 9 Interfaces graphiques avec awt. Cours 92 Plan Introduction : deux bibliothèques graphiques 1.Comment se dessine une fenêtre ?  Un exemple.
Master 1 SIGLIS Java Lecteur Stéphane Tallard Les erreurs communes en Java.
Interfaces graphiques. Composants d'interface utilisateur graphique (GUI) 1 Bibliothèques Awt et Swing Procédures communes pour l'utilisation de ces clases.
14 La gestion d’événements
Tutorat en bio-informatique
Les classes et les objets Les données finales class A { … private final int n = 20 ; // la valeur de n est définie dans sa déclaration … } class A { public.
© Sofia ZAIDENBERGCNRS Mai Interfaces Graphiques Tracer une fonction y = f(x) avec JAVA 2D.
© Sofia ZAIDENBERG CNRS Mai Interface utilisateur graphique en Java Construire une interface graphique en Java (suite) adaptateurs d’événements.
PROGRAMMATION INFORMATIQUE D’INGÉNIERIE II
Transcription de la présentation:

Interfaces Graphiques Dessiner avec JAVA Contexte Graphique Rafraîchissement Java2D

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 Java 2D Graphics Jonathan Knudsen, Ed. O'Reilly Java 2D API Graphics Vincent J. Hardy, Java Series, Prentice Hall

Adaptateurs d’événements Dessin des segments de droite Gestion des événements souris Déplacement de la souris sur la zone de dessin met à jour les coordonnées du curseur dans la barre d’état MOUSE_MOVED, MOUSE_DRAGGED type d’événement : MouseEvent source : zone de dessin interface d’écoute : MouseListener récepteur : zone de dessin Appuyer sur un bouton de la souris (MOUSE_PRESSED) définit le début d’une droite Relâcher le bouton de la souris (MOUSE_RELEASED) définit la fin de la droite < interface > MouseListener void mouseClicked(MouseEvent) void mouseEntered(MouseEvent) void mouseExited(MouseEvent) void mousePressed(MouseEvent) void mouseReleased(MouseEvent) Comme pour la fermeture de la fenêtre seule deux des méthodes de l ’interface nous intéressent

Adaptateurs d’événements 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) { } // ZoneGraphique Pour ne pas avoir à définir des méthodes inutiles possibilité d’utiliser un adaptateur d’événements : MouseAdapter 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()); addMouseListener(new GestionnaireClic(this)); public void initieDroite(int x, int y) { be.afficheMessage("Relacher pour dessiner la droite"); // on complétera ensuite } public void termineDroite(int x, int y) { be.afficheMessage("Cliquer pour initier une droite");

Adaptateurs d’événements 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 complétera ensuite public void termineDroite(int x, int y) { be.afficheMessage(« Cliquer pour initier une droite »); ... } // ZoneGraphique Avec une classe interne (« inner class ») anonyme addMouseListener( ); new MouseAdapter() { public void mousePressed(MouseEvent e) { initieDroite(e.getX(),e.getY()); } public void mouseReleased(MouseEvent e) termineDroite(e.getX(),e.getY()); L’instance de la classe anonyme a implicitement accès à l’instance de la classe externe qui (c.-à-d. l’instance) a provoqué sa création : en conséquence elle a accès aux membres de la classe externe ZoneDessin.this

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 complétera ensuite public void termineDroite(int x, int y) { be.afficheMessage(« Cliquer pour initier une droite »); ... } // ZoneGraphique addMouseListener( ); new MouseAdapter() { public void mousePressed(MouseEvent e) { initieDroite(e.getX(),e.getY()); } public void mouseReleased(MouseEvent e) termineDroite(e.getX(),e.getY()); Comment dessiner avec Java ? // on complétera ensuite // on complétera ensuite

Contexte Graphique Ici le support du dessin est représenté par une instance de la classe JPpanel avec java.awt dans la plupart des cas il s’agit d’une instance de la classe Canvas Il faut des outils pour dessiner : primitives géométriques (droites, cercles, rectangles …) gestion des attributs de tracé (couleur du trait, couleur de remplissage, polices de caractères …) Ces outils sont représentés en Java par la classe Graphics du package java.awt 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. Classe abstraite : les instances de cette classe sont fournies à la demande par le système d’exploitation qui, grâce à la machine virtuelle, instanciera une sous-classe de Graphics spécifique à la plate-forme utilisée méthodes de Graphics pour dessiner des formes

Dessiner avec Java Dessin des segments de droite Repère graphique X y type d’événement : MouseEvent Appuyer sur un bouton de la souris (MOUSE_PRESSED) définit le début d’une droite Relâcher le bouton de la souris (MOUSE_RELEASED) définit la fin de la droite x y ? ? x y 150 50 250 110 Coordonnées position de la souris Exprimées dans le repère de la source de l’événement : le JPanel

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é : mémoriser le début d’un nouveau segment Lorsque le bouton de la souris est relâché : Graphics g = this.getGraphics(); 1) Récupérer le contexte graphique associé au JPanel g.drawLine(xInit,yInit,x,y); 2) Utiliser l’objet Graphics pour effectuer le dessin

Dessiner en Java « rafraichissement » du dessin Problème de réaffichage après que la fenêtre ait été masquée, redimensionnée… GO 1 Zone non rafraichie 2 Application seule ne peut pas décider du moment où elle doit être rafraîchie Le système ne prend pas en charge seul le rafraîchissement avertit uniquement l’application qu’elle doit se redessiner (en lui indiquant quel est son rectangle invalide) à la charge de celle-ci de se redessiner 3

Affichage d'un composant Quand un composant est-il affiché ? À la demande du système (« System triggered painting ») quand le composant est rendu visible pour la première fois quand le composant a été recouvert puis découvert  appel de la méthode paint(Graphics g) du composant À la demande de l’application (« Application triggered painting ») quand le programme ou un composant Swing détermine que le composant doit être réaffiché en interne dans les Swing (changement d’un texte, d’une couleur...) dans votre propre programme en faisant une demande explicite de réaffichage  appel de la méthode repaint() du composant place une demande d’affichage dans la file d’attente des événements le thread de gestion des événements se chargera d’appeler la méthode paint() ne jamais appeler paint() directement, toujours utiliser repaint()

Affichage d'un composant Que fait la méthode paint() ? 1) Le fond (background) (si opaque) 2) Affichage spécifique (custom painting) (si présent) 3) Bordure (border) (si présent) 4) Les fils (children) (si présent) paintComponent(Graphics g) paintBorder(Graphics g) paintChildren(Graphics g) dessine le composant lui-même déjà implémentée pour les composants standards (fenêtres, boutons, …) doit être redéfinie (« overriden ») pour créer vos propres composants Dessine les bordures ajoutées au composant (en utilisant setBorder) Ne pas appeler directement cette méthode ni la redéfinir.

Affichage d'un composant Un composant se dessine avant chacun des composants qu’il contient L’affichage d’une interface Swing s’effectue récursivement en descendant la hiérarchie des containers bouton 1 bouton 2 composant qui affiche du texte Œ fenêtre contentPane panneau gauche panneau droite composant texte bouton1 bouton2  Ž  ordre d’affichage  ‘ ’

Affichage d'un composant Pour résumer Chaque composant graphique possède une méthode qui définit comment il doit se dessiner public void paint(Graphics g) pour les composants awt public void paintComponent(Graphics g) pour les composants swings Évidemment pour les composants standards (fenêtres, boutons, …) il est inutile de définir comment ils doivent s’afficher une fenêtre affichera son cadre et son fond puis affichera tout les composants qu’elle contient un conteneur affichera son fond puis affichera récursivement tous les composants qu’il contient … Mais dès que l’application gère ses propres graphiques via un contexte graphique (objet Graphics) elle devra se soucier de leur rafraichissement et redéfinir paintComponent

Dessiner en Java « rafraichissement » du dessin Redessiner les segments de droite disparus il faut stocker les informations pour afficher à nouveau tous les segments déjà dessinés classes SegmentDroite et Dessin Java 2 (1.4) 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 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);

Dessiner en Java « rafraichissement » du dessin Redessiner les segments de droite disparus il faut stocker les informations pour afficher à nouveau tous les segments déjà dessinés classes SegmentDroite et Dessin Java 5 (1.5) 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 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<SegmentDroite> lesDroites = new ArrayList<SegmentDroite>(); for (SegmetDroit d : lesDroites) { d.dessineToi(g); }

Dessiner en Java « rafraichissement » du dessin 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 d’un objet dessin pour mémoriser les segments dessinés Mémorisation des nouveaux objets tracés SegmentDroite droite = new SegmentDroite(x,y,xInit,yInit,couleurCourante); dessin.ajouterDroite(droite); droite.dessineToi(g); Redéfinition de la méthode paintComponent pour gérer le réaffichage Permet de dessiner l’arrière plan sinon l’affichage du fond doit être fait explicitement ou setOpaque(false) doit être invoquée pour informer le système d’affichage de Swing que les composants situés derrière peuvent être visibles et doivent en conséquence être affichés public void paintComponent(Graphics g) { super.paintComponent(g); dessin.dessineToi(g); }

Dessiner en Java rafraichissement du 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("Défaire"); this.add(bDefaire); JButton bEffacer = new JButton("Tout effacer"); this.add(bEffacer); bDefaire.addActionListener( ); bEffacer.addActionListener( } Efface toute la zone de dessin Annule le dernier tracé new ActionListener() { public void actionPerformed(ActionEvent e) { zd.annule(); } type d’événement : ActionEvent source : les JButton interface d’écoute : ActionListener new ActionListener() { public void actionPerformed(ActionEvent e) { zd.efface(); } Récepteurs : utilisation de classes anonymes dans le constructeur de la Barre d’Outils

Dessiner en Java rafraichissement du dessin import java.awt.*; import javax.swing.*; import java.awt.event.*; public class ZoneDessin extends Jpanel implements MouseMotionListener { private BarreEtat be; private int xInit, yInit; Dessin dessin new Dessin(); public ZoneDessin(BarreEtat be) { ... } public void initieDroite(int x, int y) { public void termineDroite(int x, int y) { public void paintComponent(Graphics g) { } // ZoneDessin Prise en compte des opérations annuler et effacer sur la zone de dessin public void annule() { dessin.annule(); } 1) Modification de l’objet mémorisant le dessin 2) réaffichage de la zone de dessin Il faut prévenir l’application que le dessin a changé et qu’il faut rafraîchir le composant repaint(); Méthode repaint() se charge de rappeler la méthode d’affichage du composant (paintComponent) avec le bon contexte graphique public void efface() { dessin.efface(); repaint(); }

De AWT à Java 2D Sérieuses limitations des possibilités graphiques de awt primitives graphiques limitées (lignes, rectangles, ovales...) dessin des lignes avec épaisseur d’un seul pixel peu de polices de caractères disponibles pour appliquer une rotation ou une translation à quelque chose il faut le faire soi-même support rudimentaire pour les images contrôle de la transparence très difficile ... Introduction de nouvelles API pour le graphique avec version 2 de Java  Java 2D Object Graphics De nouvelles classes dans les packages : java.awt java.awt.image java.awt.Graphics2D fourni des possibilités de dessin beaucoup plus élaborées Graphics2D This Graphics2D class extends the Graphics class to provide more sophisticated control over geometry, coordinate transformations, color management, and text layout. This is the fundamental class for rendering 2-dimensional shapes, text and images on the Java(tm) platform De nouveaux packages : java.awt.color java.awt.font java.awt.geom java.awt.print java.awt.image.renderable

Java2D Démonstration des possibilités de Graphics2D programme de démonstration dans $JAVA_HOME/demo/jfc/JAVA2D/Java2Demo.jar

Pour illustrer les possibilités de l'API Java2D import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; public class DemoJava2D1 extends JPanel{ public DemoJava2D_1() { setBackground(Color.WHITE); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); g.drawRect(100,100,100,100); public static void main(String[] args) { JFrame f = new JFrame("Demo Java 2D n°1"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we){ System.exit(0); }); f.add(new DemoJava2D_1()); f.setSize(new Dimension(400,400)); f.setVisible(true); Pour illustrer les possibilités de l'API Java2D on va débuter par un petit programme de dessin qui au départ n’utilise pas Java 2D et qui sera ensuite modifié (exemple tiré de : The Java2D API, Bill Loeb, Dr Dobb's Journal, Février 1999)

Utiliser l’objet Graphics2D public void paintComponent(Graphics g) En fait g est un objet Graphics2D, (Graphics2D est une sous classe de Graphics) On utilise le type Graphics pour des raisons de compatibilité avec les versions antérieures de l’API java Si on veut utiliser les fonctionnalités de Graphics2D il suffit de « downcaster » g Graphics2D g2D = (Graphics2D) g; g2D.draw(new Polygone(tabX, tabY, nbPts));

Utiliser l’objet Graphics2D ... public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); g.drawRect(100,100,100,100); } ... public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.BLUE); g2d.setStroke(new BasicStroke(4.0f)); g2d.drawRect(100,100,100,100); }

Utiliser des objets Shape ... public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.BLUE); g2d.setStroke(new BasicStroke(4.0f)); g2d.drawRect(100,100,100,100); } 1 Initialise le contexte graphique Définit et dessine un objet (Rectangle) 2 Dans l’API Java 2D l’affichage peut être séparé de la définition de l’objet. en général 3 étapes pour dessiner des objets Initialiser le contexte graphique Définir l’objet à dessiner Appeler l’une des méthodes de rendu de Graphics2D pour afficher l’objet Les objets implémentent l’interface java.awt.Shape Le package java.awt.geom propose différentes classes d’implémentation de Shape

Utiliser des objets Shape ... public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(Color.BLUE); g2d.setStroke(new BasicStroke(4.0f)); Rectangle2D r = new Rectangle2D.Float(100.0f, 100.0f, 200.0f, 200.0f); g2d.draw(r); } 1 Initialise le contexte graphique Définit un objet (Rectangle2D) 2 Appel de l’une des méthodes de rendu de Graphics2D 3 <interface> Shape Rectangle2D Rectangle2D.Float Rectangle2D.Double 2 classes selon le degré de précision que l’on veut adopter

Shapes : package java.awt.geom Point2D + void setLocation(double x, double y) + void setLocation(Point2d p) + double getX() + double getY() + double distance(double x, double y) + double distance(Point2d p) ... représente un point dans l’espace utilisateur point ≠ pixel 1 point n’a pas de surface, utilisé pour définir la géométrie des primitives graphiques classes membre statiques Point2D.Float + float x + float y ... Point2D.Double + double x + double y ... Point + int x + int y ... public abstract class Point2D { ... } public static class Double extends Point2D { public double x; public double y; public static class Float extends Point2D { public float x; public float y; java.awt compatibilité avec versions antérieures de java

Shapes : package java.awt.geom Line2D.Float Line2D Line2D.Double Rectangle2D RoundRectangle2D RectangularShape Ellipse2D Arc2D <interface> Shape QuadCurve2D CubicCurve2D forme arbitraire construite en spécifiant une série de points pouvant être connectés par des segments, courbes quadratiques ou cubiques GeneralPath Area opération booléennes sur deux formes

Dessiner et remplir une forme Painting : remplir l’intérieur d’une forme (« shape ») avec une couleur, un dégradé ou une texture, méthode fill de Graphics2D Stroking : dessiner le contour (« outline ») d’une forme en spécifiant l’épaisseur du trait (« line width »), le style de trait, méthode draw de Graphics2D Graphics2D g2 = (Graphics2D)g; double x = 15, y = 50, w = 70, h = 70; Ellipse2D e = new Ellipse2D.Double(x, y, w, h); Remplir une forme Œ Indique au contexte graphique comment remplir les formes. gp un objet qui implémente interface java.awt.Paint GradientPaint gp = new GradientPaint(75, 75, Color.white,95, 95, Color.gray, true); // Fill with a gradient. g2.setPaint(gp); g2.fill(e); Œ   Demande au contexte graphique de remplir la forme en la passant à la méthode fill // Stroke with a solid color. e.setFrame(x + 100, y, w, h); g2.setStroke(new BasicStroke(8)); g2.setPaint(Color.black); g2.draw(e); Dessiner le contour d’une forme Œ Œ  Indique au contexte graphique comment dessiner le contour des formes à l’aide d’un objet qui implémente interface java.awt.Stroke Ž  Indique au contexte graphique comment remplir le contour à l’aide d'objet qui implémente interface java.awt.Paint // Stroke with a gradient. e.setFrame(x + 200, y, w, h); g2.setPaint(gp); g2.draw(e); Ž Demande au contexte graphique de dessiner le contour de la forme en la passant à la méthode draw

<interface> Stroke setStroke(Stroke s) <interface> Stroke BasicStroke Épaisseur du trait (« line width ») c’est un float (1.0 -> environ 1 pixel -> 1/72 pouce lorsque la transformation par défaut est appliquée) Style de jointure (« joint style ») : la manière dont segments se raccordent Style de terminaison (« end-cap ») : la manière dont les extrémité des segments sont affichées Style de pointillé (« dash style ») JOIN_BEVEL JOIN_METER JOIN_ROUND CAP_BUTT CAP_ROUND CAP_SQUARE

Stroke ... public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setPaint(Color.BLUE); float dash[] = {20.0f, 10.0f}; g2d.setStroke(new BasicStroke( 4.0f, // line width BasicStroke.CAP_ROUND, // end cap style BasicStroke.JOIN_BEVEL, // join style 0.0f, // miter limit dash, // dash array 0.0f // dash phase )); Rectangle2D r = new Rectangle2D.Float(100.0f, 100.0f, 200.0f, 200.0f); g2d.draw(r); } ... Tableau de flottants qui représente la longueur des sections tracées et non tracées du pointillé - index pair (trait plein) - index impair (espace) float dash[] = {10.0f,6.0f,2.0f,6.0f};

<interface> Paint setPaint(Paint p) <interface> Paint Color GradientPaint TexturePaint couleur uniforme dégradé de couleur remplissage avec une texture Couleurs spécifiées par composantes primaires Rouge, Vert et Bleu public Color(int r, int g, int b) 0 .. 255 public Color(float r, float g, float b) 0.0 .. 1.0 public Color(int rgb) Color.RED 255 0 0 Color.GREEN 0 255 0 Color.BLUE 0 0 255 int Color.WHITE 255 255 255 alpha red green blue Color.BLACK 0 0 0 Color.CYAN 0 255 255 Par défaut : couleurs définies comme opaques Couleur partiellement transparente définie à l’aide du canal alpha Color.MAGENTA 255 0 255 Color.YELLOW 255 255 0 public Color(int a, int r, int g, int b) 0 .. 255 public Color(float a, float r, float g, float b) 0.0 .. 1.0 public Color(int argb, boolean hasAlpha) opaque transparent

Paint Color GradientPaint TexturePaint g2d.setStroke(new BasicStroke(4.0f)); Rectangle2D r = new Rectangle2D.Float(100.0f, 100.0f, 200.0f, 200.0f); g2d.setPaint(…); g2d.fill(r); g2d.setPaint(Color.RED); g2d.draw(r); Color GradientPaint TexturePaint

Paint GradientPaint gp = new GradientPaint( g2d.setStroke(new BasicStroke(4.0f)); Rectangle2D r = new Rectangle2D.Float(100.0f, 100.0f, 200.0f, 200.0f); g2d.setPaint(…); g2d.fill(r); g2d.setPaint(Color.RED); g2d.draw(r); GradientPaint gp = new GradientPaint( 100.f, 100.f, // starting point Color.BLUE, // starting color 200.f, 200.f, // ending point Color.GREEN // ending color ); g2d.setPaint(gp); g2d.setPaint(Color.BLUE);

Paint Création ou récupération de l’image définissant la texture g2d.setStroke(new BasicStroke(4.0f)); Rectangle2D r = new Rectangle2D.Float(100.0f, 100.0f, 200.0f, 200.0f); g2d.setPaint(…); g2d.fill(r); g2d.setPaint(Color.RED); g2d.draw(r); BufferedImage bi = new BufferedImage( 6, // width 6, // height BufferedImage.TYPE_INT_RGB // RGB image ); Graphics2D big = bi.createGraphics(); big.setColor(Color.BLUE); big.fillRect(0,0,6,6); big.setColor(Color.GREEN); big.fillRect(2,2,4,4); Création ou récupération de l’image définissant la texture Création de l’objet texture Rectangle2D rTexture = new Rectangle2D.Float(0.0f, 0.0f, 6.0f, 6.0f); TexturePaint tp = new TexturePaint(bi,rTexture); g2d.setPaint(tp);

Rendering Hints Ellipse2D r = new Ellipse2D.Float(100.0f, 100.0f, 200.0f, 200.0f); GradientPaint gp = new GradientPaint( 100.f, 100.f, // starting point Color.BLUE, // starting color 200.f, 200.f, // ending point Color.GREEN // ending color ); g2d.setPaint(gp); // g2d.fill(r); g2d.setStroke(new BasicStroke(10.0f)); g2d.draw(r); g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY

Transformations géométriques Graphics2D maintient une transformation géométrique appliquée au primitives géométriques avant qu’elles ne soient rendues. Attribut défini comme une instance de AffineTransform transformation affine : lignes parallèles demeurent parallèles composition de transformations élémentaires translation rotation x' = x + tx y' = y + ty x' = x . cos(Θ) - y . sin(Θ) y' = x . sin(Θ) + y . cos(Θ) homothétie (scaling) shearing x' = a . x y' = b . y x' = x + shx . y y' = y ou x' = x y' = shy . x + y Même l’épaisseur du trait est affectée ! Une épaisseur de 0.0 produira un tracé le plus fin possible

transformations géométriques AffineTransform Maintient représentation source d’une matrice 3x3 d’une transformation affine [x'] = [m00 m01 m02] [x] = [m00x + m01y + m02] [y'] = [m10 m11 m12] [y] = [m10x + m11y + m12] [1] = [ 0 0 1 ] [1] = [ 1 ] « Factory » méthodes pour construire de transformations élémentaires public static AffineTransform getTranslateInstance(double tx,double ty) public static AffineTransform getRotateInstance(double theta) public static AffineTransform getRotateInstance(double theta,double x,double y) public static AffineTransform getScaleInstance(double sx,double sy) public static AffineTransform getShearInstance(double shx,double shy) Composition de transformations public void concatenate(AffineTransform Tx) [this] = [this] x [Tx] Tx sera appliquée en premier aux coordonnées des primitives géométriques La composition n’est pas commutative. L’ordre des transformations compte ! translation puis rotation rotation puis translation public void preConcatenate(AffineTransform Tx) [this] = [Tx] x [this]

transformations géométriques Graphics2D gère une transformation affine courante Graphics2D passé en paramètre de paintComponent initialisée avec une transformation par défaut plaçant origine dans le coin supérieur gauche de la surface de dessin du composant Modification de la transformations courante public abstract void setTransform(AffineTransform Tx) Remplace la transformation courante public abstract void transform(AffineTransform Tx) Concaténation à la transformation courante public abstract void translate(double tx, double ty) public abstract void rotate(double theta) public abstract void rotate(double theta, double x, double y) public abstract shear(double shx, double shy) Attention : setTransform écrase la transformation courante qui peut être utilisée pour d’autres choses (par exemple pour positionner les composants swing contenus dans la fenêtre) Œ Utiliser getTransform pour récupérer la transformation courante Utiliser les étapes suivantes pour appliquer des transformations  Utiliser transform, translate, scale, shear ou rotate pour modifier la transformation courante Ž Effectuer le rendu  Restituer la transformation originale en utilisant setTransform

transformations géométriques g2d.setStroke(new BasicStroke(4.0f)); Rectangle2D r = new Rectangle2D.Float(100.0f, 100.0f, 200.0f, 200.0f); g2d.setPaint(Color.BLUE); g2d.fill(r); g2d.setPaint(Color.RED); g2d.draw(r); AffineTransform t = new AffineTransform(); t.rotate(Math.toRadians(45)); g2d.setTransform(t); AffineTransform t = new AffineTransform(); t.translate(200,200); t.rotate(Math.toRadians(45)); t.translate(-200,-200); g2d.setTransform(t);

transformations géométriques Possibilité de modifier les coordonnées d’une primitive graphique sans modifier la transformation courante de Graphics2D Création d’une nouvelle Shape public Shape createTransformedShape(Shape pSrc) public Point2D transform(Point2D ptSrc, Point2D ptDst) public void transform(Point2D[] ptSrc,int srcOff,Point2D[] ptDst, int dstOff,numPts) public Point2D deltaTransform(Point2D ptSrc, Point2D ptDst) public void deltaTransform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) Pour transformer un vecteur (« delta ») représenté par un point. N’applique pas la composante de translation de la transformation courante.

Créer se propres formes GeneralPath gp = new GeneralPath(); Line2D l1 = new Line2D.Float(50.f,100.f,100.f,100.f); gp.append(l1,true); CubicCurve2D cc = new CubicCurve2D.Float( 100.0f, 100.0f, // starting point 125.0f, 125.0f, // control point 1 150.0f, 125.0f, // control point 2 175.0f, 100.0f // ending point ); gp.append(cc,true); Line2D l2 = new Line2D.Float(175.0f,100.0f, 225.0f,100.0f); gp.append(l2,true); g2d.setStroke(new BasicStroke(4.0f)); g2d.setPaint(Color.BLUE); g2d.draw(gp); for (int i = 0; i < 10; i++) { g2d.translate(20,20); }

Créer se propres formes Rectangle2D r = new Rectangle2D.Float(100.0f, 100.0f, 100.0f, 100.0f); Ellipse2D e = new Ellipse2D.Float(150.0f, 150.0f, 25.0f, 25.0f); Area a = new Area(r); a.subtract(new Area(e)); g2d.setStroke(new BasicStroke(4.0f)); g2d.setPaint(Color.BLUE); g2d.fill(a); g2d.setPaint(Color.RED); g2d.draw(a); g2d.translate(120,120); g2d.translate(150,150); g2d.scale(2,2); g2d.rotate(Math.toRadians(45)); g2d.translate(-150,-150);

Support de l’nteraction utilisateur Pour interagir avec les dessins affichés, nécessité de déterminer lorsque l’utilisateur clique sur l’un deux. Deux manières de procéder : en utilisant la méthode hit de Graphics2D public abstract boolean hit(Rectangle rect, Shape s, boolean onStroke)  true si la forme s intersecte le rectangle rect exprimé en coordonnées écran (« device coordinates ») en utilisant la méthode contains de l’objet Shape public boolean contains(double x, double y)  true si la forme s contient le point x, y exprimé en coordonnées écran (« device coordinates »)

Attributs du contexte Graphics2D Style de pinceau (« pen style ») pour dessiner le contour des formes épaisseur du trait, pointillé, ... setStroke Style de remplissage (« fill style ») appliqué à l'intérieur des formes couleur de remplissage, dégradés, textures. setPaint Style de composition (« composition style ») utilisé quand les objets affichés recouvrent d’autres objets (transparence,...) setComposite Transformation géométrique. Application de transformations géométriques (translations, rotations, homothétie (« scaling »), « shearing »...) aux formes setTransform Clipping. Restreint l’affichage à une région définie par une forme géométrique setClipping Police (« font ») utilisée pour le texte setFont « Rendering hints » : préférence dans compromis entre rapidité et qualité du rendu. Par exemple pour spécifier si l’antialiasing doit être utilisé où non setRenderingHints

Rendu dans java 2D Graphics2D Graphics primitives fill() draw() drawString() drawImage() transformation Shapes Text Images stroke font rendering hints rasterizer Dispositifs D’affichage écran imprimante clipping shape paint composition rule images D’après JAVA 2D Graphics de Jonathan Knudsen, Ed. Oreilly