|
|
|
|
|
|
|
Dibuixar i pintar... |
|
|
|
|
|
Sovint convé
presentar a l'usuari d'una certa aplicació Java
alguna mena de diagrama, de dibuix, de representació. Això
implica la necessitat de disposar d'algun conjunt de classes i mètodes
que ens permetin elaborar aquests diagrames, dibuixos i representacions.
|
|
|
|
|
|
Grosso modo, a Java,
tots els objectes de les classes derivades de la classe
java.awt.Component tenen un context gràfic que permet pintar-hi
a sobre tota mena de formes. El control de l'acte de pintar el té
un objecte de la classe java.awt.Graphics o de
la classe java.awt.Graphics2D que representa aquest
context gràfic. Les esmentades classes, java.awt.Graphics
i java.awt.Graphics2D contenen els mètodes
necessaris per dibuixar el que calgui. |
|
|
|
|
|
Precisem-ho una mica més
(no pas gaire, encara!): Tota classe derivada de la classe java.awt.Component
conté el mètode |
|
|
|
|
|
public
void paint (Graphics g) |
|
|
|
|
|
|
el qual és cridat cada
vegada que el component es dibuixa o redibuixa a la pantalla. El qua cal
fer, aleshores, és sobreescriure (override) aquest métode
per tal que el component es dibuixi segons allò que el programador
desitja. |
|
|
|
|
|
La classe
Graphics |
|
|
|
|
|
La classe java.awt.Graphics
representa el context gràfic d'un component i conté un seguit
de mètodes per fer dibuixos diversos: |
|
|
|
|
|
- public void setColor(Color c).
Selecciona l'objecte java.awt.Color, (veure
més avall) el qual determina
el color amb què es pintaran tots els dibuixis següents,
fins una nova crida a setColor().
- public void drawLine(int x1, int y1,
int x2, int y2). Dibuixa una línia entre els punts (x1,y1)
i (x2,y2).
- public void drawOval(int x, int y,
int width, int height). Dibuixa el contorn de l'el·lipse
inscrita en un rectangle de dimensions int width
i int height, amb el vèrtex superior
de l'esquerra a la posició (x,y).
- public void fillOval(int x, int y,
int width, int height). Dibuixa l'interior de l'el·lipse
inscrita en un rectangle de dimensions int width
i int height, amb el vèrtex superior
de l'esquerra a la posició (x,y).
- public void drawRect(int x, int y,
int width, int height). Dibuixa el contorn del rectangle de dimensions
int width i int height,
amb el vèrtex superior de l'esquerra a la posició (x,y).
- public void fillRect(int x, int y,
int width, int height). Dibuixa l'interior del rectangle de dimensions
int width i int height,
amb el vèrtex superior de l'esquerra a la posició (x,y).
- public void drawRoundRect(int x, int
y, int width, int height, int arcWidth, int arcHeight). Dibuixa
el contorn del rectangle de vèrtexs arrodonits de dimensions
int width i int height,
amb el vèrtex superior de l'esquerra a la posició (x,y).
Els paràmetres int arcWidth i int
arcHeight determinen les dimensions de l'arc d'arrodoniment dels
vèrtexs.
- public void fillRoundRect(int x, int
y, int width, int height, int arcWidth, int arcHeight). Dibuixa
l'interior del rectangle de vèrtexs arrodonits de dimensions
int width i int height,
amb el vèrtex superior de l'esquerra a la posició (x,y).
Els paràmetres int arcWidth i int
arcHeight determinen les dimensions de l'arc d'arrodoniment dels
vèrtexs.
- public void draw3DRect(int x, int
y, int width, int height, boolean raised). El mateix que drawRect(),
però ara la línia té relleu positiu si raised
és true i regatiu si raised
és false.
- public void fill3DRect(int x, int
y, int width, int height, boolean raised). El mateix que fillRect(),
però ara l'interior del rectangle té relleu positiu si
raised és true
i regatiu si raised és false.
- public void drawString(String str,
int x, int y). Pinta la cadena de text representada per l'String
str, a la posició (vèrtex superior esquerre del
rectangle que la conté) (x,y). Cal
remarcar que el resultat és text pintat, no editable ni
seleccionable!
- public void setFont(Font font).
Selecciona el font amb el qual es pintaran les cadenes de text.
|
|
|
|
|
|
Les coordenades, en aquestos
contextos gràfics, són nombres enters (int)
que compten píxels. El punt o píxel (0,0) és
a dalt a l'esquerra, la primera coordenada (x,
width o similar) creix d'esquerra a dreta i la
segona (y, height, etc.)
de dalt a baix: |
|
|
|
|
|
|
|
|
|
|
|
La classe java.awt.Graphics
conté encara molts d'altres mètodes, que trobareu perfectament
descrits a la documentació corresponent. |
|
|
|
|
|
La classe
java.awt.Color |
|
|
|
|
|
A
Java
tot són classes
i no podia ésser d'altra manera amb el color! Examina ara la documentació
de la classe
java.awt.Color. Si vols
obtenir un determinat color pots acudir directament als camps
static d'aquesta classe: |
|
|
|
|
|
Color Color.BLACK
Color Color.BLUE
Color Color.CYAN
Color Color.DARK_GRAY
Color Color.GRAY
Color Color.GREEN
Color Color.LIGHT_GRAY
Color Color.MAGENTA
Color Color.ORANGE
Color Color.PINK
Color Color.RED
Color Color.WHITE
Color Color.YELLOW
|
|
|
|
|
|
o bé,
construir el color RGB
amb algun dels mètodes constructors
de java.awt.Color. Per
exemple, això
|
|
|
|
|
|
|
|
|
|
|
|
és completament equivalent
a això altre |
|
|
|
|
|
setColor(new
Color(0,0,255)); |
|
|
|
|
|
|
El mètode constructor
fet servir aquí és aquest: |
|
|
|
|
|
public
Color(int vermell,int verd,int blau); |
|
|
|
|
|
|
i els paràmetres int
vermell, int verd i int
blau són nombres enters entre 0 i 255. |
|
|
|
|
|
DIbuixar i pintar sobre un
JPanel: |
|
|
|
|
|
 |
Ara pots comprovar com funciona
tot això: a un objecte JFrame, canvia-li
l'objecte contentPane que porta per defecte per
un objecte JPanel, que és l'adequat per
pintar-hi a sobre (JPanel és una classe
filla de Component): |
|
|
|
|
 |
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;
/**
* Escriviu aquí una descripcìó de la classe
ProvaDePintura
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class ProvaDePintura extends JFrame {
/**
* Mètode constructor per a objectes
de la classe ProvaDePintura
*/
public ProvaDePintura() {
setTitle("Proves
de pintura");
//
Un JPanel com a nou contentPane del JFrame
JPanel cnt=new
JPanel();
//
Cal donar-li dimensions, perquè no contindrà cap
// component,
només s'hi dibuixarà a sobre
cnt.setPreferredSize(new
Dimension(300,200));
//
Ara se substitueix el contentPane per defecte pel
// JPanel creat
setContentPane(cnt);
pack();
show();
}
}
|
|
|
|
|
|
|
Ara ja tens preparada la superfície
per pintar-hi: |
|
|
|
|
 |
|
|
|
|
|
|
Només cal que sobreescriguis
(override) el mètode paint() del
JPanel. Com que només faràs això,
no cal crear una classe nova sinó que amb intercalar el nou mètode
paint() en la construcció del JPanel
n'hi ha prou: |
|
|
|
|
 |
import
javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
/**
* Escriviu aquí una descripcìó de la classe
ProvaDePintura
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class ProvaDePintura extends JFrame {
/**
* Mètode constructor per a objectes
de la classe ProvaDePintura
*/
public ProvaDePintura() {
setTitle("Proves
de pintura");
//
Un JPanel com a nou contentPane del JFrame. Se subs-
// titueix (override)
el mètode paint() original per un
// de nou
JPanel
cnt=new JPanel() {
public void
paint (Graphics g) {
//
Un rectangle "enfonsat" blanc
g.setColor(Color.WHITE);
//
El "marc"
g.draw3DRect(4,4,292,192,false);
//
El "fons"
g.fillRect(5,5,290,190);
//
Un rectangle arrodonit vermell amb
//
contorn negre
g.setColor(Color.RED);
g.fillRoundRect(50,30,200,150,25,20);
g.setColor(Color.BLACK);
g.drawRoundRect(50,30,200,150,25,20);
//
Un text de color blau
g.setColor(Color.BLUE);
g.setFont(new
Font("Serif",
Font.PLAIN,30));
g.drawString("Això
és un text",10,70);
//
Una el·lipse marró sense contorn
g.setColor(new
Color(180,100,0));
g.fillOval(190,100,100,50);
}
};
//
Cal donar-li dimensions, perquè no contindrà cap
// component,
només s'hi dibuixarà a sobre
cnt.setPreferredSize(new
Dimension(300,200));
// Ara se substitueix
el contentPane per defecte pel
// JPanel creat
setContentPane(cnt);
pack();
show();
}
}
|
|
|
|
|
|
|
Observa com ha estat escrit aquest
codi: Abans de tancar la línia |
|
|
|
|
|
|
|
|
|
|
|
amb el corresponent punt i coma
(;) s'obre un espai entre una parella de claus
({ ... }) a l'interior del qual hi ha escrit el
nou codi del mètode paint(). Aquesta
manera de procedir és útil si no cal modificar massa la classe
JPanel (o la que sigui del cas), pero si no, més
val crear una classe filla de JPanel a part, i
codificar-ne els mètodes amb més comoditat: |
|
|
|
|
 |
import
javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
/**
* Escriviu aquí una descripcìó de la classe
ProvaDePintura
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class ProvaDePintura extends JFrame {
/**
* Mètode constructor per a objectes
de la classe ProvaDePintura
*/
public ProvaDePintura() {
setTitle("Proves
de pintura");
//
Un ElMeuPanel com a nou contentPane del JFrame.
ElMeuPanel
cnt=new ElMeuPanel();
//
Com abans, cal donar-li dimensions, perquè no
// contindrà
cap component, només s'hi dibuixarà
// a sobre
cnt.setPreferredSize(new
Dimension(300,200));
// Ara se substitueix
el contentPane per defecte pel
// JPanel creat
setContentPane(cnt);
pack();
show();
}
}
/**
* La classe ElMeuPanel és un JPanel amb una implementació
* particular del mètode paint():
*/
class ElMeuPanel extends JPanel {
/**
* Mètode paint per a objectes
de la classe ElMeuPanel.
* @override paint de la classe JPanel
*/
public void paint (Graphics g) {
//
Un rectangle "enfonsat" blanc
g.setColor(Color.WHITE);
//
El "marc"
g.draw3DRect(4,4,292,192,false);
//
El "fons"
g.fillRect(5,5,290,190);
//
Un rectangle arrodonit vermell amb
// contorn negre
g.setColor(Color.RED);
g.fillRoundRect(50,30,200,150,25,20);
g.setColor(Color.BLACK);
g.drawRoundRect(50,30,200,150,25,20);
//
Un text de color blau
g.setColor(Color.BLUE);
g.setFont(new Font("Serif",
Font.PLAIN,30));
g.drawString("Això
és un text",10,70);
//
Una el·lipse marró sense contorn
g.setColor(new
Color(180,100,0));
g.fillOval(190,100,100,50);
}
}
|
|
|
|
|
|
|
En ambdós casos, després
de construir un objecte ProvaDePintura, el resultat
és aquest: |
|
|
|
|
 |
|
|
|
|
|
|
La
classe Graphics2D |
|
|
|
|
|
A partit de la primera edició del SDK
que es va dir Java
2 (SDK
versions 1.2 i següents) la capacitat gràfica de Java
es va posar d'acord amb els progressos i les noves possibilitats de les
targetes gràfiques dels ordenadors. Es posà a la disposició
dels programadors la nova classe java.awt.Graphics2D,
filla de la vella classe java.awt.Graphics,
amb moltíssimes millores incorporades. Des d'aleshores, els contextos
gràfics són, en realitat, de la classe Graphics2D
i no de la classe Graphics, però, per
compatibilitat amb versions anteriors del SDK,
calia conservar objectes Graphics com a paràmetres
dels mètodes paint().
|
|
|
|
|
|
En conseqüència,
per tal que l'objecte controlador del context gràfic actui com a
objecte de la classe Graphics2D cal fer el càsting
corresponent (no t'oblidessis pas d'importar la classe java.awt.Graphics2D!): |
|
|
|
|
 |
<codi
anterior>
/**
* Mètode paint per a objectes
de la classe ElMeuPanel.
* @override paint de la classe JPanel
*/
public void paint (Graphics g) {
//
Objecte Graphics g convertit a objecte Graphics2D
Graphics2D
g2D=(Graphics2D)g;
//
A partir d'ara, qui diguixa és l'objecte g2D:
//
Un rectangle "enfonsat" blanc
g2D.setColor(Color.WHITE);
//
El "marc"
g2D.draw3DRect(4,4,292,192,false);
//
El "fons"
g2D.fillRect(5,5,290,190);
//
Un rectangle arrodonit vermell amb
// contorn negre
g2D.setColor(Color.RED);
g2D.fillRoundRect(50,30,200,150,25,20);
g2D.setColor(Color.BLACK);
g2D.drawRoundRect(50,30,200,150,25,20);
//
Un text de color blau
g2D.setColor(Color.BLUE);
g2D.setFont(new
Font("Serif",
Font.PLAIN,30));
g2D.drawString("Això
és un text",10,70);
//
Una el·lipse marró sense contorn
g2D.setColor(new
Color(180,100,0));
g2D.fillOval(190,100,100,50);
}
}
|
|
|
|
|
|
|
RenderingHints |
|
|
|
|
|
|
Es poden aconseguir ara millores en el rendering gràfic.
Els objectes de la classe Graphics2D poden suggerir
a la targeta gràfica de la màquina algunes maneres de presentar
els gràfics i, si la targeta ho pot fer, ho fa. Aquests suggeriments
són objectes de la classe java.awt.RenderingHints.
El mètode corresponent és de la classe Graphics2D
i és:
|
|
|
|
|
|
public
void setRenderingHint(RenderingHints.Key hintKey,
Object
hintValue) |
|
|
|
|
|
|
Per exemple, si volem antialiasing,
aleshores cal fer servir els valors RenderingHints.KEY_ANTIALIASING
i RenderingHints.VALUE_ANTIALIAS_ON: |
|
|
|
|
 |
<codi
anterior>
/**
* Mètode paint per a objectes
de la classe ElMeuPanel.
* @override paint de la classe JPanel
*/
public void paint (Graphics g) {
// Objecte Graphics
g convertit a objecte Graphics2D
Graphics2D g2D=(Graphics2D)g;
// A partir d'ara,
qui diguixa és l'objecte g2D:
// El RenderingHint
per activar antialiasing
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Un rectangle
"enfonsat" blanc
g2D.setColor(Color.WHITE);
// El "marc"
g2D.draw3DRect(4,4,292,192,false);
<codi següent>
|
|
|
|
|
|
|
Mira què passa: |
|
|
|
|
 |
|
|
|
|
|
|
Veus la millora? Mira que, ara,
els contorns queden ben perfilats i no esglaonats (pixelats, se'n
diu d'això!) com abans. Si amplies la lletra "A"
d'"Això",
ho veuràs més bé: |
|
|
|
|
|
|
|
|
Sense
antialiasing |
Amb antialiasing |
|
|
|
|
|
La resta de renderingHints,
com aquest, té a veure amb les diverses maneres de renderitzar
gràfics i és, més aviat, objecte d'un curs de gràfics
que d'un curs de Java
com aquest. |
|
|
|
|
|
Shapes (formes) |
|
|
|
|
|
|
Una segona millora de la classe
Graphics2D respecte de la classe Graphics
és la capacitat de dibuixar el contorn (draw)
o l'interior (fill) dels objectes que implementen
la interfície (interface) java.awt.Shape
(forma). Els mètodes són: |
|
|
|
|
|
public
void draw(Shape forma) |
|
|
|
|
|
|
i |
|
|
|
|
|
public
void fill(Shape forma) |
|
|
|
|
|
|
Pots fer proves amb un objecte
java.awt.Polygon, que inclou l'interfície
Shape. Aquesta classe representa un polígon
i el constructor és |
|
|
|
|
|
public
Polygon(int[] xPunts, int[] yPunts, int numPunts) |
|
|
|
|
|
|
Les matrius de nombres enters
xPunts i yPunts contenen,
respectivament, les coordenades x i y
dels vèrtexs del polígon i numPunts
és el nombre de vèrtexs (que, com és lògic,
no ha de ser més gran que les longituds (xPunts.length
i yPunts.length) de les matrius de les coordenades.
Ara, el mètode paint() de la classe ProvaDePintura
quedaria així: |
|
|
|
|
 |
/**
* Mètode paint per a objectes
de la classe ElMeuPanel.
* @override paint de la classe JPanel
*/
public void paint (Graphics g) {
// Objecte Graphics
g convertit a objecte Graphics2D
Graphics2D g2D=(Graphics2D)g;
// A partir d'ara,
qui diguixa és l'objecte g2D:
// El RenderingHint
per activar antialiasing
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Un rectangle
"enfonsat" blanc
g2D.setColor(Color.WHITE);
// El "marc"
g2D.draw3DRect(4,4,292,192,false);
// El "fons"
g2D.fillRect(5,5,290,190);
//
Les coordenades "x" de set vèrtexs d'un polígon
int[]
lesX={50,120,190,250,200,150,80};
//
Les coordenades "y" de set vèrtexs d'un polígon
int[]
lesY={110,20,90,10,190,140,190};
//
Construcció del polígon:
Polygon
poligon=new Polygon(lesX,lesY,7);
//
L'interior del polígon de color blau:
g2D.setColor(Color.BLUE);
g2D.fill(poligon);
//
El contorn del polígon de color negre:
g2D.setColor(Color.BLACK);
g2D.draw(poligon);
}
|
|
|
|
|
|
|
No oblidis importar la classe
java.awt.Polygon! |
|
|
|
|
|
Obtindràs això: |
|
|
|
|
 |
|
|
|
|
|
|
Transformacions
afins |
|
|
|
|
|
|
Finalment, la classe Graphics2D
és capaç de modificar les coordenades de les formes que pinta
segons transformacions afins. Parlant molt en general, una
transformació afí és una transformació
del pla que conserva paral·lelismes i proporcions: translacions,
rotacions, simetries i homotècies són
transformacions afins, però n'hi ha moltes altres. |
|
|
|
|
|
Ara cal una mica de Matemàtiques:
una transformació afí vé determinada per una matriu
de tres files i tres columnes |
|
|
|
|
|
|
|
|
|
|
|
i, per trobar el transformat del
punt (x, y),
se'l considera com a un vector amb la tercera component igual a 1
i s'opera segons la pràctica habitual "fila per columna": |
|
|
|
|
|
|
|
|
|
|
|
Els termes mij
determinen la mena de transformació i els termes tij
són les components de la translació subseqüent a la transformació.
Cal que tinguis en compte que, si els termes tij
són zero, aleshores no hi ha translació i el punt (0,0)
queda fix! |
|
|
|
|
|
Algunes transformacions habituals
són: |
|
|
|
|
|
|
Translació
de p
unitats cap a la dreta i q
unitats cap a baix. Si cal anar cap a l'esquerra o cap a dalt, els corresponents
valors han de ser negatius. |
|
|
|
|
|
|
Ampliació
p vegades
en direcció horitzontal i q
vegades en direcció vertical. Si cal reduir, els valors han de ser
més petits que 1. |
|
|
|
|
|
|
Rotació
d'angle A
a l'entorn del punt (0,0). |
|
|
|
|
|
|
Simetria
respecte d'una recta que passa pel punt (0,0)
i inclinada un angle A. |
|
|
|
|
|
La classe java.awt.geom.AffineTransform
representa aquestes transformacions. El mètode constructor és |
|
|
|
|
|
public
AffineTransform(double m00, double m10,
double
m01, double m11,
double
t02, double t12) |
|
|
|
|
|
|
Per exemple, per girar 30º i,
després traslladar 150 a la dreta i 100 cap a baix, cal fer |
|
|
|
|
|
AffineTransform
afTr=new AffineTransform(0.866,0.5,
-0.5,0.866,
150,100); |
|
|
|
|
|
 |
Pots provar ara com funcionen les
transformacions afins. Comença per traslladar el polígon de
l'exemple d'abans per tal que inclogui el punt (0,0).
És qüestió de restar 150
a les coordenades x
i 100 a les coordenades
y: |
|
|
|
|
 |
/**
* Mètode paint per a objectes
de la classe ElMeuPanel.
* @override paint de la classe JPanel
*/
public void paint (Graphics g) {
// Objecte Graphics
g convertit a objecte Graphics2D
Graphics2D g2D=(Graphics2D)g;
// A partir d'ara,
qui diguixa és l'objecte g2D:
// El RenderingHint
per activar antialiasing
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Un rectangle
"enfonsat" blanc
g2D.setColor(Color.WHITE);
// El "marc"
g2D.draw3DRect(4,4,292,192,false);
// El "fons"
g2D.fillRect(5,5,290,190);
// Les coordenades
"x" de set vèrtexs d'un polígon
int[]
lesX={-100,-30,40,100,50,0,-70};
// Les coordenades
"y" de set vèrtexs d'un polígon
int[]
lesY={10,-80,-10,-90,90,40,90};
// Construcció
del polígon:
Polygon poligon=new
Polygon(lesX,lesY,7);
// L'interior del
polígon de color blau:
g2D.setColor(Color.BLUE);
g2D.fill(poligon);
// El contorn del
polígon de color negre:
g2D.setColor(Color.BLACK);
g2D.draw(poligon);
}
|
|
|
|
|
|
|
A veure si ho has fet bé? |
|
|
|
|
 |
|
|
|
|
|
|
Sí, sí, ja està
bé. Ara cal introduir la transformació. El mètode és
de la classe Graphics2D i és |
|
|
|
|
|
public
void setTransform(AffineTransform afTr) |
|
|
|
|
|
|
Som-hi! |
|
|
|
|
 |
/**
* Mètode paint per a objectes
de la classe ElMeuPanel.
* @override paint de la classe JPanel
*/
public void paint (Graphics g) {
// Objecte Graphics
g convertit a objecte Graphics2D
Graphics2D g2D=(Graphics2D)g;
// A partir d'ara,
qui diguixa és l'objecte g2D:
// El RenderingHint
per activar antialiasing
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//
La transformació:
AffineTransform
afTr=new AffineTransform(0.866,0.5,
-0.5,0.866,
150,100);
//
Un rectangle "enfonsat" blanc
g2D.setColor(Color.WHITE);
// El "marc"
g2D.draw3DRect(4,4,292,192,false);
// El "fons"
g2D.fillRect(5,5,290,190);
// Les coordenades
"x" de set vèrtexs d'un polígon
int[] lesX={-100,-30,40,100,50,0,-70};
// Les coordenades
"y" de set vèrtexs d'un polígon
int[] lesY={10,-80,-10,-90,90,40,90};
// Construcció
del polígon:
Polygon poligon=new
Polygon(lesX,lesY,7);
//
Activació de la transformació
g2D.setTransform(afTr);
//
L'interior del polígon de color blau:
g2D.setColor(Color.BLUE);
g2D.fill(poligon);
// El contorn del
polígon de color negre:
g2D.setColor(Color.BLACK);
g2D.draw(poligon);
}
|
|
|
|
|
|
|
(Ep! ja havies importat la classe
java.awt.geom.AffineTransform?) |
|
|
|
|
|
Ara, efectivament, es veu el polígon
girat 30º i traslladat: |
|
|
|
|
 |
|
|
|
|
|
|
Un exercici: |
|
|
|
|
 |
Es tracta que aconsegueixis
una finestra pintada com aquesta: |
|
|
|
|
|
|
|
|
|
|
|
Els textos hauran de ser pintats
sense canviar el font, que sempre serà el de defecte. Les transformacions
que sofriran han de ser fetes només a partir d'aplicar successivament
el mètode |
|
|
|
|
|
public
void setTransform(AffineTransform afTr) |
|
|
|
|
|
|
amb objectes adequats de la classe
java.awt.geom.AffineTransform. |
|
|
|
|
|
Complicat, eh? Una solució
és aquí,
però espera
i no la miris!) |
|
|
|
|
|
|
 |