|
Das Anzeigen einer Bitmap kann in zwei Schritte unterteilt werden:
Das Laden erfolgt mit der Methode getImage, die eine Instanz der Klasse Image zurückgibt. Das Image-Objekt kann dann mit der Methode drawImage der Klasse Graphics angezeigt werden.
getImage gibt es in verschiedenen Varianten, die sich dadurch unterscheiden, aus welcher Quelle sie die Bitmap-Daten laden. In einer Java-Applikation wird in der Regel die Methode getImage aus der Klasse Toolkit verwendet. Sie erwartet den Namen einer lokalen Datei als Parameter:
public Image getImage(String filename) |
java.awt.Toolkit |
getImage versteht in der aktuellen Version des AWT die beiden Bitmap-Typen gif und jpeg. Andere Grafikformate, wie etwa das unter Windows gebräuchliche bmp-Format, werden nicht unterstützt, sondern müssen bei Bedarf konvertiert werden.
Neben den getImage-Methoden gibt es seit dem JDK 1.2 auch zwei Methoden mit dem Namen createImage in der Klasse Toolkit:
Sie laden ein Image bei jeder Verwendung neu und führen (im Gegensatz zu getImage) kein Caching des Bildes durch. Die JDK-Dokumentation empfiehlt sie gegenüber getImage, weil bei deren Verwendung Speicherlecks durch das unbegrenzte Zwischenspeichern der Bilddaten entstehen können. |
![]() |
|
![]() |
Das Toolkit für die aktuelle Umgebung kann mit der Methode getToolkit der Klasse Component beschafft werden:
public Toolkit getToolkit() |
java.awt.Component |
Der gesamte Code zum Laden einer Bitmap duke.gif sieht daher so aus:
001 Image img; 002 img = getToolkit().getImage("duke.gif"); |
Um das Image anzuzeigen, kann die Methode drawImage der Klasse Graphics aufgerufen werden:
public boolean drawImage( Image img, int x, int y, ImageObserver observer ) |
java.awt.Graphics |
drawImage gibt es in unterschiedlichen Ausprägungen. Die hier vorgestellte Variante erwartet das anzuzeigende Image-Objekt und die Position (x,y), an der die linke obere Ecke der Bitmap plaziert werden soll. Das zusätzlich angegebene Objekt observer dient zur Übergabe eines ImageObserver-Objektes, mit dem der Ladezustand der Bitmaps überwacht werden kann. Hier kann der this-Zeiger, also eine Referenz auf das Fensterobjekt, übergeben werden. Eine weitere Variante von drawImage, die ein Bild sogar skalieren und spiegeln kann, wurde in Kapitel 2 vorgestellt. Wir wollen hier nicht weiter auf Details eingehen. |
![]() |
|
![]() |
Das folgende Listing ist ein einfaches Beispiel für das Laden und Anzeigen der Bitmap duke.gif. Alle erforderlichen Aktionen erfolgen innerhalb von paint:
|
![]() |
|
![]() |
Die Ausgabe des Programms ist:
Abbildung 24.1: Laden und Anzeigen einer Bitmap
Die gewählte Vorgehensweise ist nicht besonders effizient, denn die Bitmap wird bei jedem Aufruf von paint neu geladen. Besser ist es, die benötigten Bitmaps einmal zu laden und dann im Speicher zu halten. Obwohl man vermuten könnte, daß dies die Ladezeit des Fensters unannehmbar verlängern würde, ist der Konstruktor der Klasse eine gute Stelle dafür. Der Aufruf von getImage lädt die Bitmap nämlich noch nicht, sondern bereitet das Laden nur vor. Der eigentliche Ladevorgang erfolgt erst, wenn die Bitmap beim Aufruf von drawImage tatsächlich benötigt wird. |
![]() |
|
![]() |
Manchmal kann es sinnvoll sein, den tatsächlichen Ladevorgang des Bildes abzuwarten, bevor im Programm fortgefahren wird. Wird zum Beispiel die Größe der Bitmap benötigt, um sie korrekt auf dem Bildschirm anordnen oder skalieren zu können, muß das Programm warten, bis das Image vollständig erzeugt ist.
Für diese Zwecke steht die Klasse MediaTracker zur Verfügung, die das Laden eines oder mehrerer Bilder überwacht. Dazu wird zunächst eine Instanz der Klasse angelegt:
public MediaTracker(Component comp) |
java.awt.MediaTracker |
Als Komponente wird der this-Zeiger des aktuellen Fensters übergeben. Anschließend werden durch Aufruf von addImage alle Bilder, deren Ladevorgang überwacht werden soll, an den MediaTracker übergeben:
public void addImage(Image img, int id) |
java.awt.MediaTracker |
Der zusätzlich übergebene Parameter id kann dazu verwendet werden, einen Namen zu vergeben, unter dem auf das Image zugegriffen werden kann. Zusätzlich bestimmt er die Reihenfolge, in der die Images geladen werden. Bitmaps mit kleineren Werten werden zuerst geladen.
Der MediaTracker bietet eine Reihe von Methoden, um den Ladezustand der Bilder zu überwachen. Wir wollen hier nur die Methode waitForAll betrachten. Sie wartet, bis alle Images vollständig geladen sind:
public void waitForAll() throws InterruptedException |
java.awt.MediaTracker |
Nach Abschluß des Ladevorgangs sendet waitForAll eine Ausnahme des Typs InterruptedException.
Das vollständige Beispielprogramm zur Anzeige von duke.gif sieht nun so aus:
|
![]() |
|
![]() |
Ein schönes Beispiel für die Verwendung von Bitmaps ist die Konstruktion einer Komponente BitmapComponent, die in Dialogboxen zur Anzeige von Bitmaps verwendet werden kann. Die Verwendung soll dabei so einfach wie möglich sein, d.h., außer der Übergabe des Dateinamens an den Konstruktor soll kein zusätzlicher Aufwand entstehen.
Zur Konstruktion der Komponente gehen wir in folgenden Schritten vor:
Nach diesen Ausführungen ist die Implementierung einfach:
001 /* BitmapComponent.java */ 002 003 import java.awt.*; 004 005 class BitmapComponent 006 extends Canvas 007 { 008 private Image img; 009 010 public BitmapComponent(String fname) 011 { 012 img = getToolkit().getImage(fname); 013 MediaTracker mt = new MediaTracker(this); 014 015 mt.addImage(img, 0); 016 try { 017 //Warten, bis das Image vollständig geladen ist, 018 //damit getWidth() und getHeight() funktionieren 019 mt.waitForAll(); 020 } catch (InterruptedException e) { 021 //nothing 022 } 023 } 024 025 public void paint(Graphics g) 026 { 027 g.drawImage(img,1,1,this); 028 } 029 030 public Dimension getPreferredSize() 031 { 032 return new Dimension( 033 img.getWidth(this), 034 img.getHeight(this) 035 ); 036 } 037 038 public Dimension getMinimumSize() 039 { 040 return new Dimension( 041 img.getWidth(this), 042 img.getHeight(this) 043 ); 044 } 045 } |
BitmapComponent.java |
Bei diesem Beispiel ist die Verwendung des MediaTrackers obligatorisch. Andernfalls könnte es passieren, daß zum Zeitpunkt des Aufrufs von getPreferredSize oder getMinimumSize die Bitmap noch nicht geladen ist und die Methoden getWidth und getHeight 0 zurückgeben. Dies würde dann dazu führen, daß der Layoutmanager den benötigten Platz fehlerhaft berechnet und die Komponente falsch oder gar nicht angezeigt wird. |
![]() |
|
![]() |
Die Einbindung von BitmapComponent in einen Dialog erfolgt analog zur Einbindung jeder anderen Komponente durch Aufruf der Methode add der Klasse Component. Das folgende Listing gibt ein Beispiel für die Einbindung der neuen Komponente:
|
![]() |
|
![]() |
Die Ausgabe des Programms ist:
Abbildung 24.2: Verwendung von BitmapComponent
|
Go To Java 2, Addison Wesley, Version 1.0.2, © 1999 Guido Krüger, http://www.gkrueger.com |