interfaces graphiques

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

Upload: nathan

Post on 22-Jan-2016

56 views

Category:

Documents


1 download

DESCRIPTION

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 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 1

Interfaces GraphiquesInterfaces Graphiques

Dessiner avec JAVAContexte Graphique

Rafraîchissement

Java2D

Page 2: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 2

GUIGUI BibliographieBibliographie

The JFC Tutorial: A guide to constructing GUIKathy Walrath, Mary Campione

http://java.sun.com/docs/books/tutorial/uiswing

Java Tutorial Specialized trails: Trail: 2D GraphicsDeborah Adair, Jennifer Ball and Monica Pawlan

http://java.sun.com/docs/books/tutorial/2d

Java 2D GraphicsJonathan Knudsen, Ed. O'Reilly

Java 2D API GraphicsVincent J. Hardy, Java Series, Prentice Hall

Page 3: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 3

GUIGUI Adaptateurs d’événementsDessin des segments de droite

Adaptateurs d’événementsDessin 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

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

• type d’événement : MouseEvent• source : zone de dessin• interface d’écoute : MouseListener• récepteur : zone de dessin

< 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

Page 4: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 4

GUIGUI Adaptateurs d’événementsDessin des segments de droite

Adaptateurs d’événementsDessin 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 complétera ensuite}public void termineDroite(int x, int y) { be.afficheMessage("Cliquer pour initier une droite"); // on complétera 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 à définir des méthodes inutiles possibilité d’utiliser un adaptateur d’événements : MouseAdapter

Page 5: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 5

GUIGUI Adaptateurs d’événementsDessin des segments de droite

Adaptateurs d’événementsDessin 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 »); // on complétera 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

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

Page 6: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 6

GUIGUI Dessiner avec JavaDessin des segments de droite

Dessiner avec JavaDessin 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 »); // on complétera 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 complétera ensuite

// on complétera ensuite

Page 7: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 7

GUIGUI Contexte GraphiqueContexte 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

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

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.

méthodes de Graphicspour dessiner des formes

Page 8: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 8

GUIGUI Dessiner avec JavaDessin des segments de droite

Dessiner avec JavaDessin des segments de droite

Repère graphique

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

• type d’événement : MouseEvent

Exprimées dans le repère de la source de l’événement : le JPanel

X

y

x

y

?

?

?

?

x

yCoordonnées position de

la souris

150

50

250

110

Page 9: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 9

GUIGUI Dessiner avec JavaDessin des segments de droite

Dessiner avec JavaDessin 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 JPanelg.drawLine(xInit,yInit,x,y);

2) Utiliser l’objet Graphics pour effectuer le dessin

Page 10: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 10

GUIGUI Dessiner en Java« rafraichissement » du dessin

Dessiner en Java« rafraichissement » du dessin

Problème de réaffichage après que la fenêtre ait été masquée, redimensionnée…

1

2

3

Zone non rafraichie

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

GO

Page 11: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 11

GUIGUI Affichage d'un composantAffichage d'un composant

Quand un composant est-il affiché ? À la demande du système (« System triggered painting »)

À 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()

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

ne jamais appeler paint() directement, toujours utiliser repaint()

Page 12: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 12

GUIGUI Affichage d'un composantAffichage 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)

• 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)

paintComponent(Graphics g) paintBorder(Graphics g) paintChildren(Graphics g)

Ne pas appeler directement cette méthode ni la redéfinir.

Page 13: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 13

GUIGUI

Œ

Affichage d'un composantAffichage d'un composant

Un composant se dessine avant chacun des composants qu’il contientL’affichage d’une interface Swing s’effectue récursivement en descendant

la hiérarchie des containers

bouton 1bouton 1

bouton 2bouton 2

composantqui affiche du texte

fenêtre

contentPane

panneau gauche panneau droite

composant texte bouton1 bouton2

Ž

‘ ’ordre d’affichage

Page 14: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 14

GUIGUI Affichage d'un composantAffichage 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

Page 15: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 15

GUIGUI Dessiner en Java« rafraichissement » du dessin

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

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)

Page 16: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 16

GUIGUI

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

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

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);}

Java 5 (1.5)

Page 17: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 17

GUIGUI Dessiner en Java« rafraichissement » du dessin

Dessiner en Java« rafraichissement » du dessin

Redessiner les segments de droite disparusimport 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);

public void paintComponent(Graphics g) { super.paintComponent(g); dessin.dessineToi(g);}

Redéfinition de la méthode paintComponent pour

gérer le réaffichage

Permet de dessiner l’arrière plansinon 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

Page 18: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 18

GUIGUI Dessiner en Java rafraichissement du dessin

Dessiner en Java rafraichissement du dessin

• type d’événement : ActionEvent• source : les JButton• interface d’écoute : 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("Défaire"); 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(ActionEvent e) { zd.annule(); }}

Récepteurs : utilisation de classes anonymes dans le constructeur de la Barre

d’Outils

Page 19: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 19

GUIGUI Dessiner en Java rafraichissement du dessin

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 efface() { dessin.efface(); repaint(); }

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

Page 20: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 20

GUIGUI De AWT à Java 2DDe 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

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

java.awt.Graphics2D fourni des possibilités de dessin beaucoup plus élaborées

De nouvelles classes dans les packages :• java.awt•java.awt.image

De nouveaux packages :java.awt.color java.awt.font java.awt.geom java.awt.print java.awt.image.renderable

Page 21: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 21

GUIGUI Java2DJava2D

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

Page 22: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 22

GUIGUIimport 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 Java2Don 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)

Page 23: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 23

GUIGUI Utiliser l’objet Graphics2DUtiliser l’objet Graphics2D

public void paintComponent(Graphics g)

En fait g est un objet Graphics2D, (Graphics2D est une sous classe de Graphics)

Si on veut utiliser les fonctionnalités de Graphics2D il suffit de « downcaster » g

Graphics2D g2D = (Graphics2D) g;

On utilise le type Graphics pour des raisons de compatibilitéavec les versions antérieures de l’API java

g2D.draw(new Polygone(tabX, tabY, nbPts));

Page 24: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 24

GUIGUI Utiliser l’objet Graphics2DUtiliser 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);

}

...

Page 25: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 25

GUIGUI Utiliser des objets ShapeUtiliser 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); }

...

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 1. Initialiser le contexte graphique

2. Définir l’objet à dessiner

3. 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

1 Initialise le contexte graphique

Définit et dessine un objet (Rectangle)

2

Page 26: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 26

GUIGUI Utiliser des objets ShapeUtiliser 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 desméthodes de rendude Graphics2D

3

<interface> Shape

Rectangle2D

Rectangle2D.Float Rectangle2D.Double

2 classes selon le degré de précision que l’on veut adopter

Page 27: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 27

GUIGUI Shapes : package java.awt.geomShapes : package java.awt.geom

Point2D.Float

+ float x+ float y...

Point2D.Double

+ double x+ double y...

Point

+ int x+ int y...

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

java.awtcompatibilité avec versions antérieures de java

classes membre statiques

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; ... }

point ≠ pixel1 point n’a pas de surface,utilisé pour définir la géométrie des primitivesgraphiques

Page 28: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 28

GUIGUI Shapes : package java.awt.geomShapes : package java.awt.geom

<interface>Shape

Line2DLine2D.Float

Line2D.Double

RectangularShape

Rectangle2D

RoundRectangle2D

Arc2D

Ellipse2D

forme arbitraire construite en spécifiantune série de points pouvant être connectéspar des segments, courbes quadratiques ou cubiques

QuadCurve2D

CubicCurve2D

Area

GeneralPath

opération booléennes sur deux formes

Page 29: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 29

GUIGUI Dessiner et remplir une formeDessiner 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

GradientPaint gp = new GradientPaint(75, 75, Color.white,95, 95, Color.gray, true);// Fill with a gradient.g2.setPaint(gp);g2.fill(e);

Graphics2D g2 = (Graphics2D)g;double x = 15, y = 50, w = 70, h = 70;Ellipse2D e = new Ellipse2D.Double(x, y, w, h);

// Stroke with a solid color.e.setFrame(x + 100, y, w, h);g2.setStroke(new BasicStroke(8));g2.setPaint(Color.black);g2.draw(e);

// Stroke with a gradient.e.setFrame(x + 200, y, w, h);g2.setPaint(gp);g2.draw(e);

Ž

ŒIndique au contexte graphique comment remplir les formes. gp un objet qui implémente interface java.awt.Paint

Demande au contexte graphique de remplir la forme en la passant à la méthode fill

Œ

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

Demande au contexte graphique de dessiner le contour de la forme en la passant à la méthode draw

Remplir une forme

Dessiner le contour d’une forme

Œ

Ž

Œ

Page 30: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 30

GUIGUI StrokeStroke

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

Page 31: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 31

GUIGUI StrokeStroke

...

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ésentela 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};

Page 32: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 32

GUIGUI PaintPaint

setPaint(Paint p) <interface> Paint

Color GradientPaint TexturePaint

couleur uniforme dégradé de couleur remplissage avec une texture

public Color(int r, int g, int b) 0 .. 255public Color(float r, float g, float b) 0.0 .. 1.0public Color(int rgb)

int

Couleurs spécifiées par composantes primaires Rouge, Vert et Bleu

Par défaut : couleurs définies comme opaques Couleur partiellement transparente définie à l’aide du canal alpha

public Color(int a, int r, int g, int b) 0 .. 255public Color(float a, float r, float g, float b) 0.0 .. 1.0public Color(int argb, boolean hasAlpha)

alpha red green blue

Color.RED 255 0 0

Color.BLUE 0 0 255

Color.GREEN 0 255 0

Color.WHITE 255 255 255

Color.BLACK 0 0 0

Color.CYAN 0 255 255

Color.MAGENTA 255 0 255

Color.YELLOW 255 255 0

opaque

transparent

Page 33: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 33

GUIGUI PaintPaint

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

Page 34: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 34

GUIGUI PaintPaint

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);

g2d.setPaint(Color.BLUE);

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);

Page 35: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 35

GUIGUI PaintPaint

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);

Rectangle2D rTexture = new Rectangle2D.Float(0.0f, 0.0f, 6.0f, 6.0f);

TexturePaint tp = new TexturePaint(bi,rTexture);

Création ou récupération de l’image définissantla texture

Création de l’objettexture

g2d.setPaint(tp);

Page 36: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 36

GUIGUI Rendering HintsRendering 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

);

g2d.setRenderingHint(

RenderingHints.KEY_RENDERING,

RenderingHints.VALUE_RENDER_QUALITY

);

Page 37: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 37

GUIGUI Transformations géométriquesTransformations 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

shearinghomothétie (scaling)

x' = x + txy' = y + ty

x' = x . cos(Θ) - y . sin(Θ)y' = x . sin(Θ) + y . cos(Θ)

x' = a . xy' = b . y

x' = x + shx . yy' = y

Même l’épaisseur du trait est affectée !

ou

x' = xy' = shy . x + y

Une épaisseur de 0.0 produira un tracé le plus fin possible

Page 38: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 38

GUIGUI transformations géométriquesAffineTransform

transformations géométriquesAffineTransform

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 transformationspublic void concatenate(AffineTransform Tx) [this] = [this] x [Tx]

Tx sera appliquée en premier aux coordonnées des primitives géométriquesLa composition n’est pas commutative. L’ordre des transformations compte !

[this] = [Tx] x [this]public void preConcatenate(AffineTransform Tx)

translation puis rotationrotation puis translation

Page 39: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 39

GUIGUI transformations géométriquestransformations 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 courantepublic abstract void setTransform(AffineTransform Tx)

public abstract void transform(AffineTransform Tx)

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)

Remplace la transformation courante

Concaténation à la transformation courante

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 les étapes suivantes pour appliquer des transformations

Utiliser getTransform pour récupérer la transformation courante

Utiliser transform, translate, scale, shear ou rotate pour modifier la transformation courante

Effectuer le rendu

Restituer la transformation originale en utilisant setTransform

Ž

Œ

Page 40: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 40

GUIGUI transformations géométriquestransformations 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);

Page 41: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 41

GUIGUI transformations géométriquestransformations géométriques

Possibilité de modifier les coordonnées d’une primitive graphique sans modifier la transformation courante de Graphics2D

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)

Création d’une nouvelle Shape

Pour transformer un vecteur (« delta ») représenté par un point.N’applique pas la composante de translation de la transformation courante.

Page 42: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 42

GUIGUI Créer se propres formesCré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);

g2d.draw(gp);

}

Page 43: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 43

GUIGUI Créer se propres formesCré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);

g2d.draw(a);

Page 44: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 44

GUIGUI Support de l’nteraction utilisateurSupport 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 »)

Page 45: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 45

GUIGUI Attributs du contexte Graphics2DAttributs du contexte Graphics2D

Style de pinceau (« pen style ») pour dessiner le contour des formes épaisseur du trait, pointillé, ...

Style de remplissage (« fill style ») appliqué à l'intérieur des formescouleur de remplissage, dégradés, textures.

Transformation géométrique. Application de transformations géométriques (translations, rotations, homothétie (« scaling »), « shearing »...) aux formes

« 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

setStroke

setPaint

Style de composition (« composition style ») utilisé quand les objets affichés recouvrent d’autres objets (transparence,...)

setComposite

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

setRenderingHints

Page 46: Interfaces Graphiques

© Sofia ZAIDENBERG CNRS Mai 2007 46

GUIGUI Rendu dans java 2DRendu dans java 2D

fill()

draw()

drawString()

drawImage()

transformationtransformation

strokestroke

fontfont

rendering hintsrendering hints

clipping shapeclipping shape paintpaint composition rulecomposition rule

rasterizerrasterizer

images

Shapes

Text

Images

Graphicsprimitives

DispositifsD’affichage

écranimprimante

Graphics2D

D’après JAVA 2D Graphics de Jonathan Knudsen, Ed. Oreilly