ImageIcon och bildhantering
Klassen ImageIcon
Klassen ImageIcon representerar en ikon med en bild på.
Den används (förstås) för att hantera ikoner, men går
ofta också bra att använda för bildhantering. Den ärver
ingen annan klass och är alltså inte att betrakta som ett fönster,
utan snarare som en "bildhanterare". Här är ett kort exempel,
SimpleImage.java, som visar en bild med hjälp
av en ikon. Eftersom ikonen inte är ett fönster placerar vid
den i en JLabel (se nedan). JLabel ärver av JComponent,
så nu är bilden, dvs labeln, ett fönster som till
exempel kan adderas till en frame eller hantera mushändelser.
Bildhanering från och med 1.4
Från SDK 1.4 finns ett både enkelt och kraftfullt API som heter
Image I/O och innehåller omfattande stöd för att läsa
och skriva bilder. Kör det här programmet så får du
veta vilka format din SDK stöder, CheckSupportedFormats.java. SDK 1.4.1
för linux kan läsa gif, png och jpeg och skriva png och jpeg.
Här kommer ett program som visar hur man läser en bild, ReadImage.java. Raden image = ImageIO.read(f);
är det enda som krävs för att läsa en bild från
fil. Parametern f är ett objekt av typen java.io.File
som pekar på bildfilen. Du startar programmet genom att skriva
java -Dleffe.imagename=sökväg till filen ReadImage.
Här kommer ett program som visar hur man skriver en bild, WriteImage.java. Raden image = ImageIO.write(image,
"png", f); är det enda som krävs för att läsa en
bild från fil. Parametern image är bilden som ska sparas,
"png" anger bildens format och f är ett objekt av
typen java.io.File som pekar på bildfilen.
API:et Image I/O innehåller väsentligt mer funktionalitet för
att läsa och skriva bilder men är ändå anmärkningsvärt
lättanvänt. En utförlig beskrivning av det finns här,
http://java.sun.com/j2se/1.4/docs/guide/imageio/index.html.
Bildhantering före 1.4
Ska vi sköta om bildhanteringen själva, utan hjälp av
ImageIcon, är det en del klurigheter att tänka på.
Vi går igenom det allra viktigaste med hjälp av källkoden
till klassen ImageIcon. Så här går det till när
den laddar in en bild:
MediaTracker tracker = new MediaTracker( this );
image = Toolkit.getDefaultToolkit().getImage("en-liten-bild.gif");
//rad 1
tracker.addImage(image, 0);
//rad 2
try {
tracker.waitForID(0, 5000);
//rad 3
} catch (InterruptedException e) {
System.out.println("INTERRUPTED while loading Image");
}
int loadStatus = tracker.statusID(0, false);
//rad 4
tracker.removeImage(image, 0);
//rad 5
int width = image.getWidth(imageObserver);
//rad 6
int height = image.getHeight(imageObserver);
//rad 7
På rad 1 börjar bilden med angivet namn att laddas in. Metoden
getImage() drar igång en tråd som laddar bilden, därefter
returnerar den. På rad två anropas metoden addImage i klassen
MediaTracker. MediaTracker är en hjälpklass
för bildhantering. Metoden addImage() gör ingenting med
bilden, den informerar bara MediaTracker om bilden och tilldelar
bilden ett ID (0 i det här fallet). På rad tre väntar vi på
att bilden ska laddas in, när metoden waitForID returnerar
är inladdningen avslutad, men vi vet inte hur det gick. Metoden statusID()
på rad 4 ger oss information om resultatet. Returvärdet är
OR:at av fyra konstanter i MediaTracker: LOADING, ABORTED, ERRORED,
COMPLETE. På rad fem tar vi bort bilden från MediaTrackers
lista över bilder. Rad sex och sju ger oss bredd och höjd på
den inladdade bilden. ImageObserver är ett interface som
implementeras av Component. Om bilden ännu inte vore färdigladdad
(men det är den i det här fallet) skulle metoderna returnera
-1, när sedan bildens höjd/bredd blev känd skulle metoden
imageUpdate() i ImageObserver anropas. I anropet av imageUpdate()
skickas ett antal flaggor med information om bilden. När bilden till
slut ska ritas anropas metoden drawImage(image, x, y, imageObserver)i
klassen Graphics. Även den returnerar bums om än inte
bilden hade varit färdigladdad. ImageObserver anropas på
samma sätt som beskrivits närmast ovan.