You are on page 1of 25

Læringsmål for 

forelesningen
• Objektorientering
– Objektorientert grafikk
• Java­programmering
– Grafikk med Java2D
– Egne Swing­komponenter

1    
Grafikk
tekst

linjer
1D

fasonger
2D

bilder

2    
Java2D­demo

C:\Program files\ 
java\jdk1.5.0_11\demo\jfc\
Java2D\Java2Demo.jar

3    
Output av grafikk
• En komponent får tildelt et rektangel som den kan tegne innenfor
• Når innholdet skal tegnes blir komponentens paint­metode kalt
• paint­metoden kaller tre andre metoder (i denne rekkefølge):
– paintComponent  ­ tegner komponentens eget innhold
– paintBorder – tegner rammen rundt
– paintChildren – tegner delkomponentene
• Dersom en ønsker egen grafikk, bør en subklasse JComponent eller 
JPanel og redefinere paintComponent­metoden:
public class MinKomponent extends JComponent {
...
protected void paintComponent(Graphics g) {
// tegn en linje
g.drawLine(10, 10, 50, 50);
}
...
}
4    
paintComponent­metoden
• Hver komponent har en bredde (width) og en høyde 
(height) som definerer området som er tilgjengelig
• Hver komponent har i tillegg en ramme som stjeler plass 
på innsiden og som reduserer området et bør tegnes på
– getInsets() returnerer et Insets­objekt
– Insets­objektet har 4 attributter, top, left, bottom og right, som angir hvor mange 
punkter som rammen dekker på de 4 sidene

• Før grafikken tegnes er det lurt å beregne området som er 
tilgjengelig:
Insets insets = getInsets();
int x = insets.left;
int y = insets.top;
int bredde = getWidth() - insets.left -
insets.right;
int høyde = getHeight() - insets.top -
insets.bottom;
5    
Graphics/Graphics2D­objektet
• Graphics­parameteret til paintComponent­metoden brukes 
ved tegning av alt innhold
• parametret er deklarert som en Graphics, men for en 
JComponent­subklasse er det alltid et Graphics2D­objekt
– protected void paintComponent(Graphics g) {
Graphics2D graphics = (Graphics2D)g;
// heretter brukes graphics
• Graphics2D­objektet har essensielt to typer metoder:
– tegning av grafikk, såkalte grafikkprimitiver, f.eks.
• drawLine, drawRect, drawArc, diverse drawImage­metoder, fillRect, fillPolygon, ...
– styring av hvordan tegningen blir utført, dvs. hvordan kall til grafikkprimitivene 
farger punktene i vinduet (eller hva en nå tegner på), f.eks.
• strektype – setStroke 
• farge og mønster – setColor og setPaint
• skriftstype ­ setFont

6    
Underliggende grafikkmodell
• Matrise av punkter
– adresseres med x,y­koordinater (double­verdier)
– hvert punkt er kvadratisk (!)
• Hvert punkt har en farge
– en kan bruke et visst antall farger på en gang (2, 256, ..., 2^24)
– en farge er satt sammen av mengden rødt, grønt og blått, hver angitt som 
et tall mellom 0 og 255 (8 bit)
– noen systemer tillater også en gjennomsiktighetsverdi (alpha­kanal)
– fargekonstanter for de vanligste fargene finnes i Color­klassen
• Grafikk­primitiver
– omsettes til sett av punkt­verdier (rasterering)
– kombineres med punktene som er der fra før,
som regel ved å overskrive fargeverdien som er der fra før

7    
Graphics2D­objektet
• Alt som vises i vinduet er resultatet av kall 
til Graphics2D­metoder
• Graphics2D­objekter brukes også for å 
tegne bilder (Image) programmatisk

• Nøkkelen til grafikkprogrammering ligger i 
å forstå mulighetene som Graphics2D­
objektet gir!
8    
Graphics2D og bilder
• Graphics2D har metoder for å tegne bilder
– alle heter drawImage og tar inn et Image og en posisjon (x, y)
– bilder kan skaleres ved å angi en størrelse (bredde, høyde) som 
bildet tegnes innenfor
• Bilder representeres generelt av klassen Image, 
med BufferedImage som den mest 
anvendelige subklassen
• Bilder kan lages på flere måter
– en bildefil kan lastes inn, f.eks. angitt ved en URL
– en kan lage tomme (og gjennomsiktige) bilder som siden kan 
tegnes på vha. et spesielt Graphics2D­objekt (mer om det siden)
9    
Innlesing av bilder
• ImageIO­klassen inneholder statiske 
metoder for bl.a. å lese inn bilder
– ImageIO.read(InputStream) – fra strøm
– ImageIO.read(URL) – fra URL, f.eks. http:// eller file:/
– ImageIO.read(File) – fra File, f.eks. C:/temp/

• read­metodene returnerer BufferedImage­
instanser, som kan
– tegnes vha. Graphics2D med g2d.drawImage(BufferedImage, 
BufferedImageOp op, int x, int y) // op kan være null
– tegnes på vha. et spesiell Graphics2D­objekt (mer om det siden)
10    
Innlesing av bilder
• Bilder kan legges inn i et Java­prosjekt og 
leses inn vha. en spesiell teknikk
– legg bildefilen(e) i undermapper til en mappe som er markert som 
source­mappe, f.eks. direkte i src­mappa eller en egen resources­
mappe
– lag en InputStream til filen vha. 
obj.getClass().getResourceAsStream(”<filnavn>”);
– obj er et objekt definert i prosjektet ditt og kan gjerne være this
– filnavn er enten
• et absolutt filnavn med sti tilsvarende pakkestrukturen
• et relativt filnavn (evt. uten sti), tilsvarende pakkestrukturen ift. obj 
sin pakke
– InputStream­objektet gis så til ImageIO.read(InputStream) og du 
får et BufferedImage i retur
11    
Innlesing av bilder: Eksempel
• En klasse MyComponent
ligger i pakken java2d i
src­mappa (se figur) 
• En bildefil hal.PNG
ligger i pakken/mappen
java2d i resources­mappa
– resources­mappa er laget vha. New­>Source Folder... eller som en vanlig mappe og 
markert som en source­mappe, vha. høyreklikk og Build Path­>Use as Source Folder
– undermapper lages vha. New­>Package, som vanlig
• I MyComponent­klassen kan en nå lage en InputStream til 
filen vha.
– // absolutt sti
this.getClass().getResourceAsStream(”/java2d/hal.PNG”);
– // relativ sti til MyComponent sin pakke 
this.getClass().getResourceAsStream(”hal.PNG”); 

12    
Lage tomt og
gjennomsiktig bilde
public BufferedImage lagGjennomsiktigBilde(int w, int h) {
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
int rød = 0, grønn = 0, blå = 0, transparens = 255;
int fargeverdi = rød << 24 | grønn << 16 | blå << 8 |
transparens;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, fargeverdi);
}
}
return image;
}

13    
Tegne på et bilde­objekt
• En lager et spesielt Graphics2D­objekt for 
bildet, vha. Image.createGraphics()­metoden
public Image lagBildetegning (int w, int h) {
BufferedImage image = lagGjennomsiktigBilde(w, h);
// lag et Graphics2D-objekt for å tegne i bildet
Graphics2D graphics = image.createGraphics();
graphics.drawLine(0, 0, w, h);
// si fra at graphics-objektet ikke trengs mer
graphics.dispose();
return image;
}

14    
Tegne på et bilde­objekt
• En kan også be en JComponent om å tegne i 
bildet, ved å kalle paint­metoden med en 
bilde­Graphics2D
public Image lagJComponentbilde(int w, int h,
JComponent comp) {
BufferedImage image = lagGjennomsiktigBilde(w, h);
Graphics2D graphics = image.createGraphics();
comp.setSize(w, h);
comp.paint(graphics);
graphics.dispose();
return image;
}

15    
Tegne på et bilde­objekt
• En kan lage et bilde med tekst i, vha. JLabel
public Image lagTekstbilde(int w, int h, String s) {
JLabel label = new JLabel(s);
return lagJComponentbilde(w, h, label);
}

• En kan også lage en Cursor (muspeker) vha. et bilde!
public static Cursor lagCursor(Image image,
String name, int x, int y) {
return Toolkit.getDefaultToolkit().createCustomCursor(
image, new java.awt.Point(x, y), name);
}

16    
Graphics2D­tilstander

• font – Font
• farge – Color
• transformasjon – Transform
• blandingsregel – Composite
• maling – Paint
• strek – Stroke
17    
Output av grafikk

• Koordinatsystem
– lokalt koordinatsystem oversettes til enhetskoordinater
– koordinater kan speiles (­x) og forskyves (x+dx)
– generelle transformasjoner

18    
Transformasjoner
• Før grafikkprimitiver gjøres om til fargede 
punkter, utføres en transformasjon på 
koordinatene
• De nye koordinatene beregnes vha. en formel
– x’ = m11 x + m12 y + m1
– y’ = m21 x + m22 y + m2

• Eller på matriseform

[ m11 m12
m21 m22 ] [ ] +[ ] = [ ]
x
y
m1
m2
x’
y’
19    
Transformasjoner...
• Ved riktig oppbygning av matrisen, kan 
mange effekter oppnås

• translasjon
(dx, dy)
[ 1 0 dx
0 1 dy ]
• skalering 
(x0, y0, sx, sy)
[sx 0 x0(1-sx)
0 sy y0(1-sy) ]
20
• rotasjon(ø) [cos ø -sin ø 0
sin ø cos ø 0 ]
   
Transformasjoner...
• AffineTransform­objekter brukes for å 
defineren transformasjonen knyttet til et 
Graphics2D­objekt
– graphics.setTransform(transform);

• AffineTransform­klassen inneholder mange 
hjelpemetoder for å lage de vanligste 
matrisene:
– AffineTransform.getTranslateInstance(dx, dy);
– AffineTransform.getScaleInstance(sx, sy);

• Tranformasjonsmatriser kan settes sammen 
for å få kombinert effekten
– t1.concatenate(t2); // t1 endres ved å multiplisere med t2
21    
Persistent output
• Tegneprimitiver som objekter
– Istedenfor å tegne direkte vha. tegneprimitiver, kan en lage objekter 
som tegner seg selv
– Java har standardklasser for flere 2­dimenasjonale objekter som kan 
brukes istedenfor tegneprimitivene
• Shape­objekter representererer 2­dimensjonale 
figurer
– defineres vha. posisjon og utstrekning
– vet om et punkt er på innsiden eller utsiden
• Displayliste
– kontinuerlig visning av tegne­objekter, f.eks. Shape­objekter
– tegning gjennom manipulering av liste
• sette inn og fjerne elementer
• endre objekt­attributter
• Forenklende og raskere
• God støtte for valg av grafiske objekter
22    
Oppdatering av grafikk
• paint­metoden(e) kalles automatisk når vinduet trenger 
oppfriskning
– når vinduet vises første gang
– når komponenten gjøres synlig vha. setVisible
– når brukeren aktivt får vinduet/komponenten til å bli synlig, f.eks. i en JTabbedPane
• Det er bare i paint/paintComponent­metoden en kan tegne
– trenger et Graphics2D­objekt og dette kan ikke brukes utenfor paint­metodene
• Når en endrer på et objekt på som skal tegnes, f.eks. i 
mousePressed og mouseDragged­metoden, har en ikke noe 
Graphics2D­objekt å tegne med.
• Nøkkelen er å utføre endringen på Shape­objektene (eller 
hva en nå bruker), og så be Swing utføre den nødvendige 
oppfriskningen av skjermen/vinduet/komponenten
– repaint()

23    
repaint­metoden
• repaint­metoden brukes for å be Swing utføre den 
nødvendige oppfriskningen av 
skjermen/vinduet/komponenten:
– public mouseDragged(MouseEvent me) {
// endre på objektet som manipuleres med musa
rect.setRect(e.getX(), e.getY(), 20, 20);
// tving frem oppfriskning av komponentens innhold
repaint(); 
}
• Repaint ber systemet om å trigge oppfrisning av 
skjerminnholdet. Dette vil skje så snart som mulig, men 
først etter at lyttermetoden din er ferdig.
– lyttermetoder som mousePressed og mouseDragged utfører endring, kaller repaint 
og returnerer
– systemet vil så kalle paint på de nødvendige komponentene, for å at innholdet skal 
bli oppdatert
• Når man endrer en komponent, f.eks. label.setText() så blir 
repaint kalt av komponenten, men når vi lage 
24
komponenten selv, må vi også gjøre den delen av jobben
   
Læringsmål for 
forelesningen
• Objektorientering
– Objektorientert grafikk
• Java­programmering
– Grafikk med Java2D
– Egne Swing­komponenter

25    

You might also like