Der MediaTracker ist eine sehr alte Java-AWT-Klasse, bietet aber Dinge, über die auch einfachere Bildlademethoden nicht verfügen. Ein paar Details.
Um ein MediaTracker-Objekt zu erzeugen, rufen wir seinen Konstruktor mit einem einzigen Parameter vom Typ Component auf:
MediaTracker tracker = new MediaTracker( this );
Wenn wir Applet oder Frame erweitern, kann dies – so wie im Beispiel – der this-Zeiger sein. Dies zeigt aber schon die Einschränkung der Klasse auf das Laden von Bildern, denn was hat eine Musik schon mit einer Komponente zu tun?
Bilder beobachten
Nachdem ein MediaTracker-Objekt erzeugt ist, fügt die addImage(Image)-Methode ein Bild in eine Warteliste ein. Eine weitere überladene Methode addImage(Image, Gruppe ID) erlaubt die Angabe einer Gruppe. Dieser Identifizierer entspricht gleichzeitig einer Priorität, in der die Bilder geholt werden. Gehören also Bilder zur gleichen Gruppe, ist die Priorität immer dieselbe. Bilder mit einer niedrigeren Gruppennummer werden mit einer niedrigeren Priorität geholt als Bilder mit einer höheren ID. Eine dritte Methode von addImage() erlaubt die Angabe einer Skalierungsgröße. Nach dieser wird das geladene Bild skaliert und eingefügt. Sehen wir uns einmal eine typische Programmsequenz an, die dem Medienüberwacher ein Hintergrundbild sowie einige animierte Bilder überreicht:
Image bg = getImage( "background.gif" ), anim[] = new Image[MAX_ANIM]; MediaTracker tracker = new MediaTracker( this ); tracker.addImage( bg, 0 ); for ( int i = 0; i < MAX_ANIM; i++ ) { anim[i] = getImage( getDocumentBase(), "anim" + i + ".gif" ); tracker.addImage( anim[i], 1 ); }
Das Hintergrundbild wird dem MediaTracker-Objekt hinzugefügt. Die ID, also die Gruppe, ist 0. Das Bild-Array anim[] wird genauso gefüllt und überwacht. Die ID des Felds ist 1. Also gehören alle Bilder dieser Animation zu einer weiteren Gruppe.
Um den Ladeprozess anzustoßen, benutzen wir eine der Methoden waitForAll() oder waitForID(). Die waitForID()-Methode wird benutzt, um Bilder mit einer bestimmten Gruppe zu laden. Die Gruppennummer muss natürlich dieselbe vergebene Nummer sein, die bei der addImage()-Methode verwendet wurde. Beide Methoden arbeiten synchron, bleiben also so lange in der Methode, bis alle Bilder geladen wurden oder ein Fehler beziehungsweise eine Unterbrechung auftrat. Da das also das ganze restliche Programm blockieren würde, werden diese Ladeoperationen gerne in Threads gesetzt. Wie diese Methoden in einem Thread verwendet werden, zeigt das folgende Programmsegment. Der Block ist idealerweise in einer run()-Methode platziert oder, bei einem Applet, in der init()-Methode.
try { tracker.waitForID( 0 ); tracker.waitForID( 1 ); } catch ( InterruptedException e ) { return; }
Die waitForID()-Methode wirft einen Fehler aus, falls sie beim Ladevorgang unterbrochen wurde. Daher müssen wir unsere Operationen in einen try- und catch-Block setzen.
Während das Bild geladen wird, können wir seinen Ladezustand mit den Methoden checkID()überprüfen. checkID() bekommt als ersten Parameter eine Gruppe zugeordnet und überprüft dann, ob die Bilder, die mit der Gruppe verbunden sind, geladen wurden. Wenn ja, gibt die Methode true zurück, auch dann, wenn der Prozess fehlerhaft ist oder abgebrochen wurde. Ist der Ladeprozess noch nicht gestartet, dann veranlasst checkID(Gruppe) dies nicht. Um dieses Verhalten zu steuern, regt die überladene Funktion checkID(Gruppe, true) das Laden an. Beide geben false zurück, falls der Ladeprozess noch nicht beendet ist.
Eine weitere Überprüfungsfunktion ist checkAll(). Diese arbeitet wie checkID(), nur, dass sie auf alle Bilder in allen Gruppen achtet und nicht auf die ID angewiesen ist. Wie checkID() gibt escheckAll() ebenfalls in zwei Varianten. Die zweite startet den Ladeprozess, falls die Bilder noch nicht geladen wurden.
Die MediaTracker-Klasse verfügt über vier Konstanten, die verschiedene Flags vertreten, um den Status des Objekts zu erfragen. Einige der Methoden geben diese Konstanten ebenso zurück.
Konstante |
Bedeutung |
LOADING |
Ein Medien-Objekt wird gerade geladen |
ABORTED |
Das Laden eines Objekts wurde unterbrochen |
ERRORED |
Ein Fehler trat während des Ladens auf |
COMPLETE |
Das Medien-Objekt wurde erfolgreich geladen |
Tabelle: Flags der Klasse MediaTracker
Mit der Methode statusID(), welche ja den Zustand des Ladens überwacht, können wir leicht die Fälle herausfinden, in denen das Bild erfolgreich beziehungsweise nicht erfolgreich geladen werden konnte. Dazu verknüpfen wir einfach durch den Und-Operator die Konstante mit dem Rückgabewert vonstatusAll() oder statusID():
if ( (tracker.statusAll() & MediaTracker.ERRORED) != 0 )
Wie wir sehen, können wir durch solche Zeilen leicht herausfinden, ob bestimmte Bilder schon geladen sind. MediaTracker.COMPLETE sagt uns "ja", und wenn ein Fehler auftritt, dann ist der Rückgabewert MediaTracker.ERRORED. Wir wollen diese Flags nun verwenden, um in einer paint()-Methode das Vorhandensein von Bildern zu überprüfen, und wenn möglich, diese dann anzuzeigen. Erinnern wir uns daran, dass in der Gruppe 0 ein Hintergrundbild lag und in Gruppe 1 die zu animierenden Bilder. Wenn ein Fehler auftritt, zeichnen wir ein rotes Rechteck auf die Zeichenfläche und signalisieren damit, dass etwas nicht funktioniert.
public void paint( Graphics g ) { if ( tracker.statusID(0, true) == MediaTracker.ERRORED ) { g.setColor( Color.RED ); g.fillRect( 0, 0, size().width, size().height ); return; } g.drawImage( bg, 0, 0, this ); if ( tracker.statusID(1) & MediaTracker.COMPLETE) ) g.drawImage( anim[counter%MAX_ANIM], 50, 50, this ); }
class java.awt.MediaTracker
implements Serializable
- static final int ABORTED
Flag, welches anzeigt, dass das Medium nicht geladen werden konnte. Rückgabewert von statusAll() oder statusID(). - static final int ERRORED
Während des Ladens gab es Fehler. Rückgabewert von statusAll() und statusID(). - static final int COMPLETE
Medium konnte geladen werden. Rückgabewert von statusAll() und statusID(). - MediaTracker( Component comp )
Erzeugt einen MediaTracker auf einer Komponente, auf der das Bild möglicherweise angezeigt wird. - void addImage( Image image, int id )
Fügt ein Bild nichtskaliert der Ladeliste hinzu. Ruft addImage(image, id, -1, -1) auf. - void addImage( Image image, int id, int w, int h )
Fügt ein skaliertes Bild der Ladeliste hinzu. Soll ein Bild in einer Richtung nicht skaliert werden, ist -1 einzutragen. - public boolean checkAll()
Überprüft, ob alle vom MediaTracker überwachten Medien geladen worden sind. Falls der Ladeprozess noch nicht angestoßen wurde, wird dieser auch nicht initiiert. - boolean checkAll( boolean load )
Überprüft, ob alle vom MediaTracker überwachten Medien geladen worden sind. Falls der Ladeprozess noch nicht angestoßen wurde, wird dieser dazu angeregt. - boolean isErrorAny()
true, wenn eines der überwachten Bilder einen Fehler beim Laden verursachte. - Object[] getErrorsAny()
Liefert eine Liste aller Objekte, die einen Fehler aufweisen. null, wenn alle korrekt geladen wurden. - void waitForAll() throws InterruptedException
Das Laden aller vom MediaTracker überwachten Bilder wird angestoßen, und es wird so lange gewartet, bis alles geladen wurde oder ein Fehler beim Laden oder Skalieren auftritt. - boolean waitForAll( long ms ) throws InterruptedException
Startet den Ladeprozess. Die Funktion kehrt erst dann zurück, wenn alle Bilder geladen wurden oder die Zeit überschritten wurde. true, wenn alle korrekt geladen wurden. - int statusAll( boolean load )
Liefert einen mit Oder verknüpften Wert der Flags LOADING, ABORTED, ERRORED und COMPLETE. Der Ladeprozess wird bei load auf true gestartet. - boolean checkID( int id )
Überprüft, ob alle Bilder, die mit der ID id verbunden sind, geladen wurden. Der Ladeprozess wird mit dieser Methode nicht angestoßen. Liefert true, wenn alle Bilder geladen sind oder ein Fehler auftrat. - boolean checkID( int id, boolean load )
Wie checkID(id). Allerdings werden nur die Bilder geladen, die bisher noch nicht geladen wurden. - boolean isErrorID( int id )
Liefert den Fehlerstatus von allen Bildern mit der ID id. true, wenn eines der Bilder beim Laden einen Fehler aufweist. - Object[] getErrorsID( int id )
Liefert eine Liste aller Medien, die einen Fehler aufweisen. - void waitForID( int id ) throws InterruptedException
Startet den Ladeprozess für die gegebene ID. Die Methode wartet solange, bis alle Bilder geladen sind. Bei einem Fehler oder Abbruch wird angenommen, dass alle Bilder ordentlich geladen wurden. - boolean waitForID( int id, long ms ) throws InterruptedException
Wie waitForID(), nur stoppt der Ladeprozess nach einer festen Anzahl von Millisekunden. - int statusID( int id, boolean load )
Liefert einen mit Oder verknüpften Wert der Flags LOADING, ABORTED, ERRORED und COMPLETE. Ein noch nicht geladenes Bild hat den Status 0. Ist load gleich true, dann werden die Bilder geladen, die bisher nocht nicht geladen wurden. - void removeImage( Image image )
Entfernt ein Bild von der Liste der Medienelemente. Dabei werden alle Objekte, die sich nur in der Skalierung unterscheiden, entfernt. - public void removeImage( Image image, int id )
Entfernt das Bild mit der ID id von der Liste der Medienelemente. Dabei werden auch die Objekte entfernt, bei denen sich die Bilder nur in der Skalierung unterscheiden. - public void removeImage( Image image, int id, int width, int height )
Entfernt ein Bild mit den vorgegebenen Ausmaßen und der ID id von der Liste der Medienelemente. Doppelte Elemente werden ebenso gelöscht.
Meiner Meinung nach hat der
MediaTracker
etwas an Bedeutung verloren. Für Swing-Anwendungen wurde noch von Sun zum Laden von Bildern die sehr effiziente Klassejavax.imageio.ImageIO
entwickelt.Ursprünglich sollte der
MediaTracker
auch noch beim Laden anderer Medien Unterstützung bieten, doch dieser Ansatz würde offenbar nie vollendet.