Dessin%20Java%20et%20Java%202D - PowerPoint PPT Presentation

About This Presentation
Title:

Dessin%20Java%20et%20Java%202D

Description:

Reste la m thode par excellence pour rafra chir un affichage ! ... Affichage. Java AWT. 15. Jean Berstel - Institut Gaspard Monge, Universit de Marne-la ... – PowerPoint PPT presentation

Number of Views:380
Avg rating:3.0/5.0
Slides: 50
Provided by: wwwigmU
Category:

less

Transcript and Presenter's Notes

Title: Dessin%20Java%20et%20Java%202D


1
Dessin Java et Java 2D
  • Java 2D et Swing
  • Graphics
  • repaint(), et en Swing
  • Composants de base
  • Chaîne de traitement
  • Les formes (Shape)
  • Les courbes, les aires
  • Transformations affines

2
2D et Swing deux avantages
  • Pour les composants AWT et Swing
  • Pour laffichage Graphics et Graphics2D

Concepts nouveaux Shape, Transformations, Path
Affichage de base Texte, formes
géométriques simples
Concepts nouveaux affichage sophistiqué
Affichage sophistiqué double buffering
par défaut, calcul de la zone de rafraîchissement
3
Le dessin de base
  • Les outils de dessin sont assez rudimentaires
  • des méthodes draw() et fill() pour lignes,
    rectangles, ovales, polygone
  • choix de deux modes de dessin direct ou xor
  • une zone de découpe (clipping) rectangulaire.
  • Java 2 propose des possibilités très
    sophistiquées
  • des méthods draw(Shape) et fill(Shape)
  • Choix des 8 modes de dessin
  • des zones de découpe arbitraires (en principe)
  • des transformations géométriques complexes
  • En Swing, le double buffering est automatique
    par défaut.

4
Contexte graphique
  • L'outil de dessin est le contexte graphique,
    objet de la classe Graphics. Il encapsule
    l'information nécessaire, sous forme d'état
    graphique.Celui-ci comporte
  • la zone de dessin (le composant), pour les
    méthodes draw() et fill()
  • une éventuelle translation d'origine
  • le rectangle de découpe (clipping)
  • la couleur courante
  • la fonte courante
  • l'opération de dessin (simple ou xor)
  • la couleur du xor, s'il y a lieu.
  • Chaque composant peut accéder implicitement et
    explicitement à un contexte graphique.

5
Obtenir un contexte graphique
  • On obtient un contexte graphique
  • implicitement, dans une méthode paint() ou
    update() AWT construit un contexte graphique
    passé en paramètre,
  • explicitement, dans un composant ou dans une
    image, par getGraphics(),
  • explicitement encore, en copiant un objet
    Graphics existant.
  • Un contexte graphique utilise des ressources
    systèmes. L'acquisition explicite doit être
    accompagnée, in fine, par une libération
    explicite au moyen de dispose().
  • L'acquisition explicite d'un contexte graphique
    est - dit-on - signe d'une programmation
    maladroite.

6
Un exemple
public class BonjourGribouille extends Applet
int xd, yd public void init()
addMouseListener(new Appuyeur())
addMouseMotionListener(new Dragueur())
class Appuyeur extends MouseAdapter public
void mousePressed(MouseEvent e) xd
e.getX() yd e.getY() class
Dragueur extends MouseMotionAdapter public
void mouseDragged(MouseEvent e) int x
e.getX(), y e.getY() Graphics g
getGraphics() g.drawLine(xd, yd, x, y)
xd x yd y g.dispose()
  • Accès explicite à un contexte graphique.
  • A chaque getGraphics(), un nouveau contexte est
    fourni, ne connaissant rien du précédent.

7
Sans appel explicite AWT seulement
  • Fait appel à la triplette magique
  • repaint
  • update
  • paint
  • repaint() demande un rafraîchissement. Appelle
    update(), en lui fournissant un contexte
    graphique.
  • update() par défaut efface le dessin et appelle
    paint().
  • paint() par défaut ne fait rien.
  • Ici
  • repaint() appelle update()
  • update() n'efface pas
  • paint() trace la ligne.

public class BonjourGribouille2 extends Applet
int xd, yd, x, y public void init()
idem public void update(Graphics g)
paint(g) public void paint(Graphics g)
g.drawLine(xd, yd, x, y) xd x yd y
class Appuyeur extends MouseAdapter
public void mousePressed(MouseEvent e) xd
e.getX() yd e.getY() class
Dragueur extends MouseMotionAdapter public
void mouseDragged(MouseEvent e) x
e.getX() y e.getY() repaint()

8
repaint()
Code simplifié de Component.java public void
Component.update(Graphics g)
g.setColor(getBackground()) g.fillRect(0,0,
width, height) g.setColor(getForeGround()) pai
nt(g) public void Component.paint(Graphics g)
  • C'est la méthode par excellence pour rafraîchir
    un affichage !
  • repaint()poste un appel à update(). Plusieurs
    appels peuvent être groupés.
  • update() effectue les opérations suivantes
  • efface le composant en le remplissant avec la
    couleur de fond
  • définit la couleur du contexte à la couleur de
    dessin
  • appelle paint().
  • paint() ne fait rien par défaut.
  • repaint() est appelé automatiquement à la
    retaille d'une fenêtre.
  • Pour dessiner, on redéfinit paint() ou update()
    (ou les deux).

9
repaint() en Swing
Code simplifié de ComponentUI.java public void
update(Graphics g, JComponent c) if
(c.isOpaque()) g.setColor(c.getBackground
()) g.fillRect(0,0, c.getWidth(),
c.getHeight()) paint(g, c)
  • Reste la méthode par excellence pour rafraîchir
    un affichage !
  • repaint()poste un appel à update(). Plusieurs
    appels peuvent être groupés.
  • update() appelle paint().
  • paint() appelle successivement
  • paintComponent() pour le dessin (le paint() en
    AWT)
  • paintBorder()
  • paintChildren().
  • paintComponent() par défaut appelle
    ComponentUI.update() qui efface et redessine le
    fond si le composant est opaque (JPanel lest par
    défaut).
  • Pour dessiner, on redéfinit paintComponent() et
    il est utile dappeler super.paintComponent().

10
Lignes, rectangles, ovales
  • Le contour est dessiné par draw, l'intérieur est
    rempli par fill.
  • Tracer une ligne, une ovale, un rectangle est
    sans surprise.
  • L'interaction draw et fill est usuelle si l'on
    veut voir le contour, il faut le tracer après.

11
Polygônes
  • Un polygône est une ligne polygonale fermée,
    donnée par la suite de ses points. Les premier et
    dernier points sont joints.
  • Deux constructeurs, et possibilité d'ajouter un
    point.
  • Remplissage selon la "even-odd rule".

Constructeurs Polygon() Polygon(int xp, int
yp, int np) Données npoints xpoints ypoints Méth
odes addPoint(int x, int y) contains(Point
p) contains(int x, int y) getBounds() translate(in
t dx, int dy)
12
Exemple
public void paint(Graphics g) int largeur
getSize().width int hauteur
getSize().height int dl largeur/2, dh
hauteur/2 int polx 0, dl, largeur,
dl int poly dh, 0, dh, hauteur
Polygon pol new Polygon(polx,poly,4)
g.setColor(Color.black) g.fillRect(0,0,largeur,
hauteur) g.setColor( Color.yellow)
g.fillPolygon(pol) g.setColor( Color.red)
g.fillRect(dl/2, dh/2, dl,dh) g.setColor(
Color.green) g.fillOval(dl/2, dh/2, dl,dh)
g.setColor( Color.blue) g.fillArc(dl/2, dh/2,
dl, dh, th, del)
public class Losange extends Applet int th
45, del 45 public void init()
addMouseListener(new MouseAdapter()
public void mousePressed(MouseEvent e)
th (th 10)360 repaint()
) public void paint(Graphics g) ...
13
Et en Swing
class Dessin extends JPanel int theta 45,
del 45 public void paintComponent(Graphics g)
int largeur getSize().width int
hauteur getSize().height int dl
largeur/2, dh hauteur/2 int polx 0,
dl, largeur, dl int poly dh, 0, dh,
hauteur Polygon pol new
Polygon(polx,poly,4) g.setColor(Color.bla
ck) g.fillRect(0,0,largeur,hauteur)
g.setColor( Color.yellow) g.fillPolygon(pol)
g.setColor( Color.red) g.fillRect(dl/2,
dh/2, dl,dh) g.setColor( Color.green)
g.fillOval(dl/2, dh/2, dl,dh) g.setColor(
Color.blue) g.fillArc(dl/2, dh/2, dl,
dh,theta, del) ...
public class Losange extends JApplet public
void init() setContentPane(new Dessin())
... public Dessin() addMouseListener( new
MouseAdapter() public void
mousePressed(MouseEvent e) theta
(theta 10)360 repaint()
)
14
Chaîne de traitement 2D
  • Le processus de traitement est en plusieurs
    étapes
  • déterminer ce qui doit être affiché (formes,
    textes, images)
  • appliquer les transformations géométriques et le
    clipping
  • déterminer la couleur
  • combiner avec ce qui se trouve sur la surface
  • Pour chacune de ces étapes, des multiples
    possibilités existent.

Primitives graphiques
Opérations de rendu
Affichage
Formes Textes Images
Transformations Clipping Composition
Ecran Imprimante
15
Détails
  • On obtient un objet Graphics2D par conversion
  • On améliore laffichage par antialiasing etc
  • On choisit loutil de dessin au trait (contours)

public void paintComponent(Graphics g)
Graphics2D g2 (Graphics2D) g ...
RenderingHints hints ... g2.setRenderingHints(h
ints)
Stroke stroke ... g2.setStroke(stroke)
16
Détails (suite)
  • On choisit loutil de remplissage (couleur,
    dégradé, motif)
  • On définit la forme de découpage
  • On définit une transformation géométrique entre
    lespace utilisateur et espace décran

Paint paint ... g2.setPaint(paint)
Shape clip ... g2.setClip(clip)
AffineTransfrom at ... g2.transform(at)
17
Détails (fin)
  • On ompose le dessin résultant avec le dessin
    existant
  • On définit la forme à dessiner
  • On laffiche

Composite composite ... g2.setComposite(composi
te)
Shape dessin ...
g2.fill(dessin) g2.draw(dessin)
18
Les formes (1)
  • Dans le paquetage java.awt.geom
  • Mais Polygon inchangé
  • La classe Point2D nest pas une forme
  • un point nest pastracé

Polygon
RectangularShape
Float
Line2D
Double
Shape
Area
Float
CubicCurve2D
Double
QuadCurve2D
GeneralPath
Float
Point2D
Double
Point
19
Les formes (2)
  • RectangularShape est la classe abstraite de base
    des formes qui sont décrites par un rectangle

Float
Arc2D
Double
Float
Line2D
Double
RectangularShape
Float
Ellipse2D
Double
Float
RoundRectangle2D
Double
Rectangle
20
Usage avec Graphics2D
  • La classe Graphics2D est une classe dérivée de
    Graphics
  • La méthode JComponent.paintComponent(Graphics g)
    reçoit en fait un Graphics2D.De même pour
    paint().
  • On convertit g par
  • Graphics2D g2 (Graphics2D) g
  • On utilise des méthodes
  • fill(Shape s)
  • draw(Shape s)
  • Exemple

g2.fill(new Rectangle2D.Double(x, y, 100, 100))
21
Traits
  • Les traits se dessinent avec une plume de la
    linterface Stroke, implémentée par BasicStroke.
  • Les attributs sont
  • lépaisseur (width)
  • fins de traits (end caps)
  • CAP_BUTT, CAP_ROUND, CAP_SQUARE
  • lien entre traits (join caps)
  • JOIN_BEVEL, JOIN_MITER, JOIN_ROUND
  • pointillé (dash)
  • Par défaut
  • trait continue dépaisseur 1, CAP_SQUARE,
    JOIN_MITER, miter limit 10

g2.setStroke(new BasicStroke(14,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL))
22
Détails
  • Cet exemple contient lillustration de plusieurs
    aspects

public void paintComponent(Graphics g)
Graphics2D g2 (Graphics2D) g
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASIN
G, RenderingHints.VALUE_ANTIALIAS_ON)
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY)
super.paintComponent(g2) g2.translate(getWidth(
)/2,getHeight()/2) g2.setColor(Color.green)
g2.fillOval(-taille/2,-taille/2, taille,
taille) g2.setColor(Color.black)
g2.setStroke(new BasicStroke(14,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL))
g2.drawOval(-taille/2,-taille/2, taille,
taille) double angleH 2Math.PI (minutes -
360) / (1260) double angleM 2Math.PI
(minutes - 15) / 60 GeneralPath gp new
GeneralPath() gp.moveTo((int)(0.3tailleMath.c
os(angleH)), (int)(0.3tailleMath.sin
(angleH))) gp.lineTo(0,0)
gp.lineTo((int)(0.4tailleMath.cos(angleM)),
(int)(0.4tailleMath.sin(angleM)))
g2.draw(gp)
23
Courbes de Bézier
  • Elles sont quadratiques ou cubique.
  • Elles ont trois ou quatre points deux contrôle,
    dont deux sont des extrémités.
  • La courbe est contenue dans le polygône de
    contrôle formé des trois ou quatre points.

24
Construction
  • Un constructeur de courbe cubique, en double

CubicCurve2D.Double(double x1, double y1, double
ctrlx1, double ctrly1,double ctrlx2, double
ctrly2, double x2, double 2)
  • Variantes utiles
  • les mêmes valent pour les courbes quadratiques.

CubicCurve2D.Double() // initialisée à
zéro CubicCurve2D.setCurve(double coords, int
offset) // affecte les valeurs CubicCurve2D.setCur
ve(Point2D pts, int offset) CubicCurve2D.setCur
ve(Point2D p1, Point2D cp1, Point2D cp2, Point2D
p2)
25
Aires
  • Formes que lon peut composer par des opérations
    booléennes (constructive solid geometry en 2D)
  • Toute forme est un composant
  • Les opérations sont
  • add
  • subtract
  • intersect
  • exclusiveor

26
Aires opérateurs
public void paintComponent(Graphics g)
Graphics2D g2 (Graphics2D)g ... Area
areaOne new Area(ellipse) Area areaTwo new
Area(rectangle) if (option.equals("add"))
areaOne.add(areaTwo) else if
(option.equals("intersection"))
areaOne.intersect(areaTwo) else if
(option.equals("subtract")) areaOne.subtract(areaT
wo) else if (option.equals("exclusive or"))
areaOne.exclusiveOr(areaTwo)
g2.setPaint(Color.orange) g2.fill(areaOne)
g2.setPaint(Color.black) g2.draw(areaOne)
27
Découpage
  • On peut restreindre la zone à (re)dessiner de
    deux manières
  • par la définition d'une forme de découpe
    (clipping)
  • par la spécification d'un rectangle de
    rafraîchissement dans la méthode repaint().
  • Un contexte graphique contient un rectangle de
    découpe
  • initialement toute la zone de dessin
  • modifiable par setClip() le rectangle ne peut que
    diminuer
  • La méthode repaint() de Component peut prendre en
    argument un rectangle, et limiter ainsi l'action
    à ce rectangle.

repaint() repaint(long tm) repaint(int x, int y,
int width, int height) repaint(long tm, int x,
int y, int width, int height)
28
Un exemple
  • Dans le rectangle bleu, on "repeint" des petits
    carrés, faisant ainsi apparaître le fond blanc.

class Repeindre extends Frame Repeindre()
setTitle("Repeindre") addMouseListener(new
Reveleur()) setSize(300,300)
setVisible(true) Graphics g
getGraphics() g.setColor(Color.blue)
g.fillRect(0, 0, getSize().width,
getSize().height) g.dispose() class
Reveleur extends MouseAdapter public void
mousePressed(MouseEvent e)
repaint(e.getX(), e.getY(), 30, 30)
public static void main(String args) new
Repeindre()
29
Un deuxième exemple
  • On choisit une ellipse comme région de découpage.
    On dessine une image qui paraît être
    partiellement révélée.
  • Lusage de la propriété opaque donne dautres
    effets.

class ImagePanel extends JPanel private
Image image private Ellipse2D oeil new
Ellipse2D.Double() private boolean pressed
false public ImagePanel() image new
ImageIcon("mandrill.jpg").getImage()
setPreferredSize( new Dimension(image.getWid
th(this),image.getHeight(this))) ...
setBackground(Color.black) ...
30
Laffichage
  • On ne peint que la partie qui est visible à
    travers loeil
  • et on modifie lellipse en fonction de position
    de la souris

public void paintComponent(Graphics g)
super.paintComponent(g) int width
getSize().width int height
getSize().height if (pressed)
g.setClip(oeil) g.drawImage(image, 0, 0,
this)
public void mouseDragged(MouseEvent e)
oeil.setFrameFromCenter(e.getX(), e.getY(),
e.getX() 100, e.getY() 50) repaint()
31
Découverte
  • La modification de lopacité empêche le
    rafraîchissement de la fenêtre cest comme dans
    un jeu où on gratte.

public void mousePressed(MouseEvent e)
pressed true oeil.setFrameFromCenter(e.getX()
, e.getY(), e.getX() 100, e.getY() 50) if
((e.getModifiers() MouseEvent.BUTTON3_MASK)!0)
setOpaque(!isOpaque()) repaint()
32
Couleurs
  • La classe Color permet de gérer les couleurs.
    Constantes
  • black, blue, cyan, darkGray, gray, green,
    lightGray, magenta, orange, pink, red, white,
    yellow.
  • Constructeurs rgb, p.ex. Color(int r, int g, int
    b)
  • Conversion RGBtoHSB (hue, saturation, brightness)
    et vice-versa.
  • La classe dérivée SystemColor contient des noms
    symboliques pour les couleurs du système
    contrôle, fenêtre active, menu, ombre (inspiré de
    Windows).
  • Le coefficient alpha indique la transparence (0
    opaque, 1 transparent)

33
Gribouilleur
public class JGribouille public static void
main(String args) JFrame f new
JFrame("Gribouille") f.setContentPane(new
Gribouilleur()) f.pack()
f.setVisible(true) f.setBackground(Color.yell
ow) f.addWindowListener(new Fermeur())
class Gribouilleur extends JPanel int
xd, yd, x, y Gribouilleur()
setPreferredSize(new Dimension(400,250))
addMouseListener(new Appuyeur())
addMouseMotionListener(new Dragueur())
setOpaque(false) public void
paintComponent(Graphics g) Graphics2D g2
(Graphics2D) g g2.setStroke(new
BasicStroke(3)) g2.drawLine(xd, yd, x, y)
xd x yd y ...
... class Appuyeur extends MouseAdapter
public void mousePressed(MouseEvent e) xd
e.getX() yd e.getY() class Dragueur
extends MouseMotionAdapter public void
mouseDragged(MouseEvent e) x e.getX() y
e.getY() repaint()
34
ColorChooser
  • Un composant de sélection de couleur est fourni.
    Il opère en plusieurs modèles par défaut, et peut
    être configuré.
  • Ici, initialisé avec couleur de fond.
  • Le bouton qui appelle le sélectionneur est dans
    un panneau.

JButton colorButton new JButton("Couleurs...")
colorButton.addActionListener(new
ActionListener() public void
actionPerformed(ActionEvent ae) Color c
JColorChooser.showDialog(Panneau.this,
"Sélection...", getBackground()) if (c !
null) setBackground(c) )
35
Exemple
public class Gribouille3 extends Applet int
xd, yd, x, y Color c Color.black Button
nettoyer Choice couleurs public Gribouille3()
setBackground(Color.blue) nettoyer new
Button("effacer") nettoyer.setForeground(Color.
black) nettoyer.setBackground(Color.lightGray)
couleurs new Choice() couleurs.addItem("bl
ack") couleurs.addItem("red")
couleurs.addItem("yellow") couleurs.addItem("gr
een") couleurs.setForeground(Color.black)
couleurs.setBackground(Color.lightGray) public
void init() add(nettoyer) add(new
Label("coloris ")) add(couleurs)
addMouseListener(new Appuyeur())
addMouseMotionListener(new Dragueur())
nettoyer.addActionListener(new Nettoyeur())
couleurs.addItemListener(new Coloreur())
public void update(Graphics g)
g.setColor(c) paint(g) public void
paint(Graphics g) g.drawLine(xd, yd, x, y)
xd x yd y
36
Exemple (suite)
  • Le Nettoyeur efface tout
  • L'Appuyeur relève la position

class Nettoyeur implements ActionListener
public void actionPerformed(ActionEvent e)
Graphics g getGraphics() g.clearRect(0,0,getS
ize().width, getSize().height)
g.dispose()
class Appuyeur extends MouseAdapter public
void mousePressed(MouseEvent e) xd
e.getX() yd e.getY()
  • Le Coloreur relève la nouvelle couleur

class Coloreur implements ItemListener public
void itemStateChanged(ItemEvent e) String a
(String) e.getItem() if
(a.equals("black")) c Color.black else
if (a.equals("red")) c Color.red else if
(a.equals("yellow")) c Color.yellow
else if (a.equals("green")) c
Color.green else c Color.pink
  • Le Dragueur relève la nouvelle position et
    demande le dessin

class Dragueur extends MouseMotionAdapter
public void mouseDragged(MouseEvent e) x
e.getX() y e.getY() repaint()
37
Dégradés et textures
  • GradientPaint et TexturePaint implémentent Paint
  • GradientPaint crée un dégradé entre deux couleurs
    données en deux points
  • TexturePaint répète une image plaquée dans un
    rectangle jusquà remplir la forme.

Paint paint new GradientPaint(0, 0, Color.red,
(float)getWidth()/2, (float)getHeight()/2,
Color.blue) g2.setPaint(paint) g2.fill(ellipse)
Rectangle2D anchor new Rectangle2D.Double(0,
0, 4 bufferedImage.getWidth(), 4
bufferedImage.getHeight()) Paint paint new
TexturePaint(bufferedImage, anchor)
38
La composition
  • Il y a 8 modes de composition de limage
    construite avec limage existante, numérotées par
    des constantes de la classe AlphaComposite.
  • Le coefficient alpha ne change pas ces modes,
    mais atténue seulement limpact de limage
    construite.
  • s alpha de source, d alpha de destination, le
    coefficient final du mélange est s(1-d) ou
    d(1-s).
  • On choisit le style de composition par
  • Encore faut-il que lécran accepte une couche
    alpha. En général cest non, et on dessine dans
    une image que lon affiche.

Composite composite AlphaComposite.getInstance(r
ule, alpha) g2.setComposite(composite)
39
Illustration (1)
  • Le programme dessine une ellipse rouge en alpha
    1 et, selon le choix de la règle de composition,
    la compose avec un rectangle bleu.
  • De dessin se fait dans une BufferedImage, pour
    profiter de la couche alpha.

public void paintComponent(Graphics g)
super.paintComponent(g) Graphics2D g2
(Graphics2D)g if (image null) image
new BufferedImage(getWidth(),getHeight(),
BufferedImage.TYPE_INT_ARGB) Graphics2D gI
image.createGraphics() gI.setPaint(Color.red)
gI.fill(ellipse) AlphaComposite composite
AlphaComposite.getInstance(rule, alpha)
gI.setComposite(composite) gI.setPaint(Color.bl
ue) gI.fill(rectangle) g2.drawImage(image,
null, 0, 0)
40
Illustration (2)
  • Le choix de la règle se fait par lecture de la
    comboBox
  • le calcul de alpha se fait par lecture dans le
    curseur (et division par 100)

if (r.equals("CLEAR)) rule AlphaComposite.CLEA
R else if (r.equals("SRC")) rule
AlphaComposite.SRC else if (r.equals("SRC_OVER"))
rule AlphaComposite.SRC_OVER else if
(r.equals("DST_OVER")) rule
AlphaComposite.DST_OVER etc.
a curseur.getValue() alpha (float)a / 100.0F
41
Transformations affines
  • Les transformations affines servent à modifier
    les coordonnées utilisateur avant affichage
  • Par exemple, le repère peut être centré au milieu
    de la zone de dessin.
  • Les transformations sont
  • rotation
  • translation
  • dilatation
  • cisaillement (shear)
  • La class AffineTransform permet de créer et de
    composer des transformations affines. De
    nombreuses méthodes existent.

42
Opérations
  • Mathématiquement, une transformation affine est
    représentée par une matrice 3 x 3 dont la
    dernière ligne est toujours (0 0 1).
  • Seuls les 6 autres coefficients sont conservés.
    On peut donner ces coefficients explicitement, ou
    les faire calculer en fonction de la nature de
    lopération recherchée.
  • Créations
  • Compositions

AffineTransform t new AffineTransform() t.setTo
Rotation(angle) t.setToTranslation(dx,
dy) t.setToScale(sx, sy) t.setToShear(cx,cy)
t.rotate(angle) t.translate(dx, dy) t.scale(sx,
sy) t.shear(cx,cy)
43
Utilisation exemple
  • Quand la transformation est définie, on lutilise
    en lajoutant à la transformation courante par

public void paintComponent(Graphics g)
super.paintComponent(g) Graphics2D g2
(Graphics2D)g g2.translate(getWidth() / 2,
getHeight() / 2) g2.setPaint(Color.gray)
g2.draw(square) g2.transform(t)
g2.setPaint(Color.red) g2.fill(smallsquare)
g2.setPaint(Color.black) g2.draw(square)
44
Exemple
  • Ici, composer est une variable booléenne qui
    conserve létat de la coche.

public void actionPerformed(ActionEvent event)
JToggleButton source (JToggleButton)
event.getSource() // le bouton String
sourceAction source.getActionCommand() // son
libellé if (sourceAction.equals("composer"))
// la coche composer source.isSelected()
return if (!composer) t.setToIdentity()
// composer ou non ? if (sourceAction.equals("r
otation")) t.rotate(Math.toRadians(30))
else if (sourceAction.equals("translater"))
t.translate(20, 15) else if (sourceAction.equal
s("dilater")) t.scale(2.0, 1.5) else if
(sourceAction.equals("cisailler"))
t.shear(-0.2, 0) repaint()
45
Transformation affine implicite
  • Laffichage, lors de lexécution dun
    paintComponent, est optimisé. Seule la zone qui
    doit être rafraîchie lest vraiment, et cela
    dépend bien sûr de lévénement qui a provoqué
    laffichage.
  • Le context graphique maintient une transformation
    affine qui contient la translation du composant
    daffichage par rapport au rectangle de
    réaffichage. Cette transformation implicite ne
    doit pas être ignorée, mais utilisée.
  • On ajoutera donc des transformations, au lieu de
    les remplacer.
  • Moyennant cette précaution, le décalage est
    transparent à lutilisateur.

46
Exemple
  • Toute opération graphique se fait relativement au
    panneau jaune.
  • Lorigine est le coin supérieur gauche du
    panneau.
  • Les valeurs numériques donnent la position de la
    souris relativement à lorigine (elle est à
    lorigine de la zone bleue).
  • La transformation affine affichée indique la
    translation de lorigine du panneau jaune par
    rapport à lorigine de la zone qui a été
    redessinée. Dans le cas présent, cette origine
    est la zone de texte.

47
Exemple (suite)
  • Ici, lorigine est la zone grise, après un
    déplacement de la barre verticale du panneau
    mouvant.
  • Une déiconification, ou le lancement, donnent
    lorigine dans la zone bleue, un déplacement du
    panneau horizontal dans la zone blanche.
  • Les informations sobtiennent par

public void paintComponent(Graphics g)
Graphics2D g2 (Graphics2D) g
... AffineTransform at g2.getTransform() txt.
setText(at.toString()) ... g2.draw(new
Ellipse2D.Float(w/4,h/4, w/2, h/2))
48
Rendu
  • Le rendu est amélioré (au dépens de la rapidité)
    par un ensemble de hints (conseils).
  • Chaque conseil concerne un aspect et indique un
    souhait.
  • Un conseil se présentent donc comme un couple
    clé dune propriété et valeur de cette propriété.
  • On peut aussi écrire

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASIN
G, RenderingHints.VALUE_ANTIALIAS_ON) g2.setR
enderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY)
RenderingHints r ... g2.setRenderingHints(r)
49
Rendu suite
  • Les aspects du rendu concernent lanti-aliasing,
    la couleur, linterpolation

KEY_ANTIALIASING VALUE_ANTIALIAS_DEFAULT
VALUE_ANTIALIAS_OFF VALUE_ANTIALIAS_ON
KEY_RENDERING VALUE_RENDER_DEFAULT
VALUE_RENDER_QUALITY VALUE_RENDER_SPEED
KEY_ALPHA_INTERPOLATION KEY_COLOR_RENDERING
KEY_DITHERING KEY_INTERPOLATION
VALUE_ALPHA_INTERPOLATION_DEFAULT
VALUE_ALPHA_INTERPOLATION_QUALITY
VALUE_ALPHA_INTERPOLATION_SPEED
KEY_FRACTIONALMETRICS KEY_TEXT_ANTIALIASING
Write a Comment
User Comments (0)
About PowerShow.com