Rita egna bilder i Swing

Sven-Olof Nyström
OOP med Java våren -25
Informationsteknologi
Uppsala Universitet

Skansholm: Kapitel 6-8

Rita egna bilder i Swing

Skansholm: Kapitel 7. Oracles tutorial ger mer detaljer: http://docs.oracle.com/javase/tutorial/uiswing/painting/

En komponent kan ritas om i två situationer:

  1. Om Swing-systemet vill det (om till exempel fönstret varit dolt och visas igen, eller fönstret har ändrat storlek)
  2. Om applikationen vill det (om till exempel bollen har flyttat på sig)

I båda fallen anropar Swing-systemet en metod

paintComponent(Graphics g)

Ett applikationsprogram ska aldrig anropa paintComponent(). Istället talar ett program om med anrop till metoden repaint() att det vill att komponenten ska ritas om. Swing-systemet ser till att metoden paintComponent() anropas.

Operationer på Graphics

Klassen Graphics definierar ett slags ritverktyg. Det kan vara läge att titta på dokumentationen för Graphics. De metoder som definieras här är ganska naturliga, så om du har provat på att skriva ett program för att rita en bild i nåt annat programspråk är det troligt att du känner igen dig.

Många metoder i Graphics anger koordinater x och y. Här är övre vänstra hörnet för komponenten (0,0). Om du definierar en metod paintComponent() för till exempel JFrame kommer position (0,0) attt skymmas av titelraden.

drawString(String s, int x, int y) ritar en textsträng med start i position (x,y).

setFont(Font f) väljer font för uppritning av text.

setColor(Color c) väljer färg för uppritning

drawline(int x1, int y1, int x2, int y2) ritar en linje från (x1, y1) till (x2, y2).

drawRect(int x, int y, int b, int h) ritar en rektangel med övre vänstra hörn vid (x,y), bredd b samt höjd h.

fillRect(int x, int y, int b, int h) ritar en ifylld rektangel.

drawOval(int x, int y, int b, int h) ritar en oval. Precis som rektangeln har den bredd b och höjd h.

fillOval(int x, int y, int b, int h) en ifylld oval.

drawPolygon(Polygon p) ritar en månghörning.

Det finns ett par varianter på drawPolygon(). Man kan antingen skapa ett objekt av klassen Polygon (beskrivs i Java's API) eller beskriva polygonen med två heltalsarrayer.

Rita egen bild...

Ett exempel på ett program som ritar en bild.

Vi definierar en klass Rityta som ärer från JPanel. I den definierar vi en enda metod, PaintComponent(). Metoden börjar med att anropa superklassens metod. Det är inte strikt nödvändigt i det här exemplet, men ibland kan komponenten ha ytterligare saker som ska ritas upp. (Prova att ge ritytan en bakgrundsfärg, tex.)

Sedan ritas en röd och en grön rektangel, en blå oval samt texterna "Hej" och "Hopp".

class Rityta extends JPanel {

    public void paintComponent(Graphics g) {

	super.paintComponent(g);

	g.setColor(Color.RED);
	g.fillRect(50, 50, 100, 200);

	g.setColor(Color.GREEN);
	g.fillRect(100,100, 60, 60);

	g.setColor(Color.BLUE);
	g.fillOval(170, 50, 100, 40);

	g.setFont(new Font("SansSerif", Font.BOLD, 24));
	g.setColor(Color.PINK);
	g.drawString("Hej", 190, 70);

	g.setColor(Color.RED);
	g.drawString("Hopp", 210, 100);
    }
}

Program: program/swing-1/DrawTest.java

Rita en gif-bild

Program: program/swing-1/ImageDemo.java

Som vanligt definierar jag två klasser, en (ImageDemo) som ärver av JFrame, och en (ImagePanel) som ärver av JPanel. Klassen ImagePanel har en instansvariabel anImage av klassen ImageIcon. Vi binder den till en ny bild som vi skapat genom att ange filnamnet där bilden finns i konstruktorn.

    ImageIcon anImage = new ImageIcon("sheep.gif");

I klassen ImagePanel definierar vi även metoden paintComponent, precis som i det föregående exemplet.

    public void paintComponent (Graphics g) {
	super.paintComponent(g);

	g.drawImage(anImage.getImage(), 50, 50, null);
    }

Det intressanta här är anropet till drawImage(). Detta används för att rita upp ikonens bild på angiven position. Om man vill kunna flytta bilden måste man förstås lagra bildens position. När positionen uppdaterats kan man anropa repaint() för att rita om bilden.

Så här ska fönstret se ut:

Precis som i exemplet Etikett i avsnittet f06-swing.html kan det ibland hända att javasystemet har svårt att hitta filen med bilden på ett får. I så fall kommer ImageDemo att visa ett tomt fönster.