|
Pintar... |
|
|
|
Sovint convé presentar a l'usuari 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.
La classe java.awt.Canvas
i les seves classes associades (java.awt.Graphics)
ens donen les eines per respondre a això. |
|
|
|
L'objectiu d'aquesta pràctica és,
per tant, començar a exercitar-se amb la classe
java.awt.Canvas. De passada ampliarem una mica
el coneixement sobre la classe java.awt.Font,
el qual havíem iniciat a la pràctica
4 del mòdul 5. I encara més: farem servir algun dels
mètodes i classes del paquet
(package) java.awt.io,
destinats a gestionar l'entrada i sortida
de dades a fitxers. |
|
|
|
Pintant sobre un Canvas |
|
|
|
La classe
bàsica és java.awt.Canvas,
la qual representa una àrea de la pantalla, rectangular i en blanc,
en la qual l'aplicació pot dibuixar-hi
o bé capturar esdeveniments
generats per l'usuari i localitzats
en punts concrets, sovint accions del ratolí.
- La classe
java.awt.Canvas és
un component
però no és un contenidor
(container).
Això implica que podem posar un canvas
a qualsevol container,
però que no podem posar components
en un canvas:
un canvas
no té cap layout manager
per organitzar-ne els components!
- Allò
que veiem, doncs, en un canvas,
no són pas objectes
sinó que tot hi és pintat. Per tant, ara sí
que són importants alguna mena de coordenades
que ens descriguin posicions:
en un canvas,
les coordenades
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
- Com qualsevol component,
un canvas té un color
de fons (background) i un color
de traçat (foreground)
heretats del contenidor en el qual
resideix, que es es poden canviar mitjançant els mètodes
public void setBackground(Color color) i public
void setForeground(Color color).
- La gestió del pintat efectiu es confia
a la classe java.awt.Graphics.
Els seus mètodes, entre els
quals
- public void draw3DRect(int
x, int y, int width, int height, boolean raised),
- public abstract void drawLine(int
x1, int y1, int x2, int y2),
- public abstract void drawOval(int
x, int y, int width, int height),
- public abstract void drawPolygon(int[]
xPoints, int[] yPoints, int nPoints),
- public abstract void drawPolyline(int[]
xPoints, int[] yPoints, int nPoints),
- public void drawRect(int
x, int y, int width, int height),
- public abstract void drawRoundRect(int
x, int y, int width, int height, int arcWidth, int arcHeight),
- public abstract void drawString(String
str, int x, int y),
- public void fill3DRect(int
x, int y, int width, int height, boolean raised),
- public abstract void fillArc(int
x, int y, int width, int height, int startAngle, int arcAngle),
- public abstract void fillOval(int
x, int y, int width, int height),
- public abstract void fillPolygon(int[]
xPoints, int[] yPoints, int nPoints),
- public abstract void fillRect(int
x, int y, int width, int height),
- public abstract void fillRoundRect(int
x, int y, int width, int height, int arcWidth, int arcHeight),
- public abstract void setColor(Color
c),
- public abstract void setFont(Font
font),
(vegeu la documentació de la
classe java.awt.Graphics)
- En una primera aproximació,
podem considerar que un canvas té
associat un objecte graphics que és
qui el pinta. Hom en diu el context
gràfic del canvas. Per
pintar necessitem fer una crida a aquest objecte
graphics mitjançant el mètode
public Graphics getGraphics() de la classe
java.awt.Component, mare
de la classe java.awt.Canvas.
- La classe java.awt.Canvas
té el mètode public
void paint(Graphics g), que gairebé sempre cal sobreescriure
(override). Aquest mètode
contindrà les instruccions necessàries per tal que es
pinti allò que desitgem.
- L'altre mètode
essencial de la classe java.awt.Canvas
és public void update(Graphics g),
el qual convé no sobreescriure.
Per defecte, l'execució d'aquest métode consisteix en:
- omplir el canvas
amb el color de fons i, per tant,
fer desaparèixer tot allò que hi havia pintat,
- executar el
mètode paint.
Hom pot cridar aquest mètode
directament des d'altres objectes mitjançant
el mètode de la classe
java.awt.Component (mare
de java.awt.Canvas) public
void repaint(). L'execució es fa llavors sobre el context
gràfic del canvas.
|
|
|
|
Posem tot això en funcionament: |
|
|
 |
Creem el projecte
Pintura com a "Basic
Java Application" amb el codi següent: |
|
|
|
/*
* @(#)Pintura.java 1.0 02/10/21
*
* You can modify the template of this file in the
* directory ..\JCreator\Templates\Template_1\Project_Name.java
*
* You can also create your own project template by making a new
* folder in the directory ..\JCreator\Template\. Use the other
* templates as examples.
*
*/ |
|
//package myprojects.pintura;
|
|
import java.awt.*;
import java.awt.event.*;
class Pintura extends Frame {
public Pintura() {
//constructor
|
|
ElMeuCanvas
canvas=new ElMeuCanvas();
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
add(canvas,BorderLayout.CENTER); |
|
addWindowListener(new
WindowAdapter() {
public
void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
});
}
public static void main(String args[]) {
System.out.println("Starting
Pintura...");
Pintura mainFrame = new
Pintura();
mainFrame.setSize(400,
400);
|
|
mainFrame.setTitle("Canvas"); |
|
mainFrame.setVisible(true);
}
}
|
|
class ElMeuCanvas extends Canvas {
public ElMeuCanvas () { //constructor
super();
}
public void paint (Graphics g) {
g.drawLine(5,15,150,65);
}
}
|
|
|
|
A l'executar-lo el resultat és aquest: |
|
|
|
|
|
|
|
|
|
Quin és el quid de
la qüestió? |
|
|
 |
Hem hagut de fer la subclasse ElMeuCanvas
per tal de sobreescriure-li el mètode
public void paint(Graphics g) i posar-li què
calia pintar. El color de fons (background),
negre, és el del frame al qual
pertany i la línia s'ha dibuixat groga, que és el color
de traç (foreground) també
del frame. Aquests colors s'han fixat
al constructor del frame, a les línies de codi
setBackground(Color.BLACK);
setForeground(Color.YELLOW); |
Ara cal jugar amb això:
|
|
|
|
- Comencem per intercalar una nova línia al
mètode
paint, just abans
de l'instrucció que fa pintar la línia:
public
void paint (Graphics g) { |
g.setColor(Color.RED); |
g.drawLine(5,15,150,65);
} |
i la línia es dibuixa ara de color vermell...
- Podem, també, combinar colors i dibuixos:
public
void paint (Graphics g) { |
g.setColor(Color.RED);
g.fillOval(25,15,150,75);
g.setColor(Color.BLUE);
g.fillRect(80,60,140,90);
g.setColor(Color.CYAN);
g.fillRoundRect(180,90,140,90,40,20); |
} |
- Si volem canviar el color del fons sense tocar
el color de fons (background)
del contenidor ni el color
del fons (background) del canvas
cal, primer de tot, conèixer quines són les dimensions
del canvas (variables segons el
layout manager!). Per fer-ho acudim al mètode
public Dimension getSize() de la classe
java.awt.Component (classe
mare de java.awt.Canvas). Aquest mètode
ens retorna les mides del canvas en
forma d'un objecte
java.awt.Dimension. La variable
public int width n'és l'amplada
i public int height n'ès l'alçada,
ambdues en pixels. Llavors, només cal
dibuixar un rectangle d'aquestes dimensions amb el color adequat. El
següent mètode posa el fons groc clar:
public
void paint (Graphics g) { |
Dimension
dimension=getSize();
g.setColor(new
Color(255,255,200));
g.fillRect(0,0,dimension.width,dimension.height); |
g.setColor(Color.RED);
g.fillOval(25,15,150,75);
g.setColor(Color.BLUE);
g.fillRect(80,60,140,90);
g.setColor(Color.CYAN);
g.fillRoundRect(180,90,140,90,40,20);
} |
- Per dibuixar textos podem fer:
public
void paint (Graphics g) {
Dimension dimension=getSize();
g.setColor(new
Color(255,255,200));
g.fillRect(0,0,dimension.width,dimension.height);
g.setColor(Color.RED);
g.fillOval(25,15,150,75);
g.setColor(Color.BLUE);
g.fillRect(80,60,140,90);
g.setColor(Color.CYAN);
g.fillRoundRect(180,90,140,90,40,20); |
g.setColor(Color.WHITE);
g.drawString("Això
és un text",100,120); |
} |
-
I, per canviar el font,
public
void paint (Graphics g) {
Dimension dimension=getSize();
g.setColor(new
Color(255,255,200));
g.fillRect(0,0,dimension.width,dimension.height);
g.setColor(Color.RED);
g.fillOval(25,15,150,75);
g.setColor(Color.BLUE);
g.fillRect(80,60,140,90);
g.setColor(Color.CYAN);
g.fillRoundRect(180,90,140,90,40,20); |
Font
f=new Font("SansSerif",Font.PLAIN,30); |
g.setColor(Color.WHITE);
g.drawString("Això
és un text",100,120);
} |
|
|
|
|
La classe java.awt.Font (II): |
|
|
 |
Ara és el moment d'ampliar una mica el
coneixement de la classe java.awt.Font
i estudiar com podem fer servir els fonts físics,
a més dels fonts lògics,
que ja sabíem manipular (vegeu la pràctica
4 del mòdul 5) |
|
|
|
- Recordem que els fonts
físics són els fonts
que resideixen en el sistema en el
qual s'executa l'aplicació Java,
que a WindowsXX són els
fonts que resideixen a la carpeta C:\WINDOWS\FONTS
o similar: ARIAL.TTF, COURIER
NEW NORMAL.TTF, TIMES.TTF, etc. i que
la Màquina Virtual de Java és
capaç, com a mínim, de tractar amb fonts
de tecnologia TrueType.
- Ja es veu que si la nostra aplicació,ha
de fer servir fonts físics,per començar
ha de ser capaç de llegir els fitxers
*.TTF del disc. D'entrada això implica
l'ús d'algunes classes del package
java.io que estan pensades justament per a
que Java tracti amb fitxers.
Per tant, la primera cosa a fer és importar
el package java.io:
import java.awt.*;
import java.awt.event.*; |
import java.io.*; |
- A continuació, cal crear una instància
de la classe java.io.File
que representi el fitxer *.TTF
que conté el font:
File file=new File("C:/WINDOWS/FONTS/TIMES.TTF"); |
- Ara cal construir una instància
de la classe java.io.FileInputStream
(filla de la classe
més general java.io.InputStream) que
representa la lectura del fitxer:
FileInputStream fontStream=new
FileInputStream(file); |
- Amb les dades
del fitxer *.TTF
ja llegides, ja podem construir el font.
El mètode a fer servir és
public static Font createFont(int fontFormat,InputStream
fontStream) de la classe java.awt.Font.
La variable int
fontFormat és Font.TRUETYPE_FONT
(vegeu la documentació de la
classe java.awt.Font)
i les dades són a fontStream:
Font f=Font.createFont(Font.TRUETYPE_FONT,fontStream); |
- Ja només falta donar-li les mides desitjades.
Fem servir el mètode public
Font deriveFont(float size) i li donem la
mida 28 (atenció!
els valors float
s'indiquen amb una "f"). Després
establim aquest font pel context
gràfic del canvas:
f=f.deriveFont(28f);
g.setFont(f); |
- Com que el mètode
createFont llença
les excepcions
java.awt.FontFormatException i java.io.IOException,
cal tancar-lo, junt amb les seves conseqüències,
en una estructura try
- catch. El codi resultant pel mètode
paint és aquest:
public
void paint (Graphics g) {
Dimension dimension=getSize();
g.setColor(new
Color(255,255,200));
g.fillRect(0,0,dimension.width,dimension.height);
g.setColor(Color.RED);
g.fillOval(25,15,150,75);
g.setColor(Color.BLUE);
g.fillRect(80,60,140,90);
g.setColor(Color.CYAN);
g.fillRoundRect(180,90,140,90,40,20); |
File file=new File("C:/WINDOWS/FONTS/TIMES.TTF");
try {
FileInputStream fontStream=
new FileInputStream(file);
Font f=Font.createFont(Font.TRUETYPE_FONT,
fontStream);
f=f.deriveFont(28f);
g.setFont(f);
} catch
(FontFormatException e) {
System.out.println(e.getMessage());
} catch
(IOException e) {
System.out.println(e.getMessage());
} |
g.setColor(Color.WHITE);
g.drawString("Això
és un text",100,120);
} |
- I el resultat és aquest:
|
|
|
|
Ara podeu experimentar amb
fonts i mides diversos a partir dels fitxers
*.TTF que hi hagi al vostre disc dur... |
|
|
|
|
|
|
 |
|
|
|
|