{"id":2252,"date":"2013-09-06T21:55:13","date_gmt":"2013-09-06T19:55:13","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=2252"},"modified":"2013-09-06T21:55:13","modified_gmt":"2013-09-06T19:55:13","slug":"mit-dem-mediatracker-arbeiten","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2013\/09\/mit-dem-mediatracker-arbeiten\/","title":{"rendered":"Mit dem MediaTracker arbeiten"},"content":{"rendered":"<p>Der MediaTracker ist eine sehr alte Java-AWT-Klasse, bietet aber Dinge, \u00fcber die auch einfachere Bildlademethoden nicht verf\u00fcgen. Ein paar Details.<\/p>\n<p>Um ein <b>MediaTracker<\/b>-Objekt zu erzeugen, rufen wir seinen Konstruktor mit einem einzigen Parameter vom Typ Component auf:<\/p>\n<pre>MediaTracker tracker = new MediaTracker( this );<\/pre>\n<p>Wenn wir Applet oder Frame erweitern, kann dies &#8211; so wie im Beispiel &#8211; der this-Zeiger sein. Dies zeigt aber schon die Einschr\u00e4nkung der Klasse auf das Laden von Bildern, denn was hat eine Musik schon mit einer Komponente zu tun?<\/p>\n<p><b>Bilder beobachten<\/b><\/p>\n<p>Nachdem ein MediaTracker-Objekt erzeugt ist, f\u00fcgt die <b>addImage(Image)<\/b>-Methode ein Bild in eine Warteliste ein. Eine weitere \u00fcberladene Methode <b>addImage(Image, Gruppe ID)<\/b> erlaubt die Angabe einer Gruppe. Dieser Identifizierer entspricht gleichzeitig einer Priorit\u00e4t, in der die Bilder geholt werden. Geh\u00f6ren also Bilder zur gleichen Gruppe, ist die Priorit\u00e4t immer dieselbe. Bilder mit einer niedrigeren Gruppennummer werden mit einer niedrigeren Priorit\u00e4t geholt als Bilder mit einer h\u00f6heren ID. Eine dritte Methode von <b>addImage()<\/b> erlaubt die Angabe einer Skalierungsgr\u00f6\u00dfe. Nach dieser wird das geladene Bild skaliert und eingef\u00fcgt. Sehen wir uns einmal eine typische Programmsequenz an, die dem Medien\u00fcberwacher ein Hintergrundbild sowie einige animierte Bilder \u00fcberreicht:<\/p>\n<pre>Image bg     = getImage( &quot;background.gif&quot; ),\n      anim[] = new Image[MAX_ANIM];\n\nMediaTracker tracker = new MediaTracker( this );\ntracker.addImage( bg, 0 );\n\nfor ( int i = 0; i &lt; MAX_ANIM; i++ ) {\n anim[i] = getImage( getDocumentBase(), &quot;anim&quot; + i + &quot;.gif&quot; );\n tracker.addImage( anim[i], 1 );\n}<\/pre>\n<p>Das Hintergrundbild wird dem <b>MediaTracker<\/b>-Objekt hinzugef\u00fcgt. Die ID, also die Gruppe, ist 0. Das Bild-Array anim[] wird genauso gef\u00fcllt und \u00fcberwacht. Die ID des Felds ist 1. Also geh\u00f6ren alle Bilder dieser Animation zu einer weiteren Gruppe.<\/p>\n<p>Um den Ladeprozess anzusto\u00dfen, benutzen wir eine der Methoden <b>waitForAll()<\/b> oder <b>waitForID()<\/b>. Die <b>waitForID()<\/b>-Methode wird benutzt, um Bilder mit einer bestimmten Gruppe zu laden. Die Gruppennummer muss nat\u00fcrlich dieselbe vergebene Nummer sein, die bei der <b>addImage()<\/b>-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\u00fcrde, 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 <b>run()<\/b>-Methode platziert oder, bei einem Applet, in der <b>init()<\/b>-Methode.<\/p>\n<pre>try {\n  tracker.waitForID( 0 );\n  tracker.waitForID( 1 );\n}\ncatch ( InterruptedException e ) { return; }<\/pre>\n<p>Die <b>waitForID()<\/b>-Methode wirft einen Fehler aus, falls sie beim Ladevorgang unterbrochen wurde. Daher m\u00fcssen wir unsere Operationen in einen try- und catch-Block setzen.<\/p>\n<p>W\u00e4hrend das Bild geladen wird, k\u00f6nnen wir seinen Ladezustand mit den Methoden <b>checkID()<\/b>\u00fcberpr\u00fcfen. <b>checkID()<\/b> bekommt als ersten Parameter eine Gruppe zugeordnet und \u00fcberpr\u00fcft dann, ob die Bilder, die mit der Gruppe verbunden sind, geladen wurden. Wenn ja, gibt die Methode true zur\u00fcck, auch dann, wenn der Prozess fehlerhaft ist oder abgebrochen wurde. Ist der Ladeprozess noch nicht gestartet, dann veranlasst <b>checkID(Gruppe)<\/b> dies nicht. Um dieses Verhalten zu steuern, regt die \u00fcberladene Funktion <b>checkID(Gruppe, true)<\/b> das Laden an. Beide geben <b>false<\/b> zur\u00fcck, falls der Ladeprozess noch nicht beendet ist.<\/p>\n<p>Eine weitere \u00dcberpr\u00fcfungsfunktion ist <b>checkAll()<\/b>. Diese arbeitet wie <b>checkID()<\/b>, nur, dass sie auf alle Bilder in allen Gruppen achtet und nicht auf die ID angewiesen ist. Wie <b>checkID()<\/b> gibt es<b>checkAll()<\/b> ebenfalls in zwei Varianten. Die zweite startet den Ladeprozess, falls die Bilder noch nicht geladen wurden.<\/p>\n<p>Die <b>MediaTracker<\/b>-Klasse verf\u00fcgt \u00fcber vier Konstanten, die verschiedene Flags vertreten, um den Status des Objekts zu erfragen. Einige der Methoden geben diese Konstanten ebenso zur\u00fcck.<\/p>\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tbody>\n<tr>\n<td valign=\"bottom\">\n<p><b>Konstante<\/b><\/p>\n<\/td>\n<td valign=\"bottom\">\n<p><b>Bedeutung<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>LOADING<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Ein Medien-Objekt wird gerade geladen<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>ABORTED<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Das Laden eines Objekts wurde unterbrochen<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>ERRORED<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Ein Fehler trat w\u00e4hrend des Ladens auf<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>COMPLETE<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Das Medien-Objekt wurde erfolgreich geladen<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><i>Tabelle: Flags der Klasse MediaTracker<\/i><\/p>\n<p>Mit der Methode <b>statusID()<\/b>, welche ja den Zustand des Ladens \u00fcberwacht, k\u00f6nnen wir leicht die F\u00e4lle herausfinden, in denen das Bild erfolgreich beziehungsweise nicht erfolgreich geladen werden konnte. Dazu verkn\u00fcpfen wir einfach durch den Und-Operator die Konstante mit dem R\u00fcckgabewert von<b>statusAll() <\/b>oder <b>statusID()<\/b>:<\/p>\n<pre>if ( (tracker.statusAll() &amp; MediaTracker.ERRORED) != 0 )<\/pre>\n<p>Wie wir sehen, k\u00f6nnen wir durch solche Zeilen leicht herausfinden, ob bestimmte Bilder schon geladen sind. <b>MediaTracker.COMPLETE<\/b> sagt uns &quot;ja&quot;, und wenn ein Fehler auftritt, dann ist der R\u00fcckgabewert <b>MediaTracker.ERRORED<\/b>. Wir wollen diese Flags nun verwenden, um in einer <b>paint()<\/b>-Methode das Vorhandensein von Bildern zu \u00fcberpr\u00fcfen, und wenn m\u00f6glich, 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\u00e4che und signalisieren damit, dass etwas nicht funktioniert.<\/p>\n<pre>public void paint( Graphics g )\n{\n  if ( tracker.statusID(0, true) == MediaTracker.ERRORED )\n  {\n    g.setColor( Color.RED );\n    g.fillRect( 0, 0, size().width, size().height );\n    return;\n  }\n  g.drawImage( bg, 0, 0, this );\n  if ( tracker.statusID(1) &amp; MediaTracker.COMPLETE) )\n    g.drawImage( anim[counter%MAX_ANIM], 50, 50, this );\n}<\/pre>\n<p><b>class java.awt.MediaTracker<br \/>\n    <br \/>implements Serializable<\/b><\/p>\n<ul>\n<li>static final int ABORTED<br \/>\n    <br \/>Flag, welches anzeigt, dass das Medium nicht geladen werden konnte. R\u00fcckgabewert von statusAll() oder statusID(). <\/li>\n<li>static final int ERRORED<br \/>\n    <br \/>W\u00e4hrend des Ladens gab es Fehler. R\u00fcckgabewert von statusAll() und statusID(). <\/li>\n<li>static final int COMPLETE<br \/>\n    <br \/>Medium konnte geladen werden. R\u00fcckgabewert von statusAll() und statusID(). <\/li>\n<li>MediaTracker( Component comp )<br \/>\n    <br \/>Erzeugt einen MediaTracker auf einer Komponente, auf der das Bild m\u00f6glicherweise angezeigt wird. <\/li>\n<li>void addImage( Image image, int id )<br \/>\n    <br \/>F\u00fcgt ein Bild nichtskaliert der Ladeliste hinzu. Ruft addImage(image, id, -1, -1) auf. <\/li>\n<li>void addImage( Image image, int id, int w, int h )<br \/>\n    <br \/>F\u00fcgt ein skaliertes Bild der Ladeliste hinzu. Soll ein Bild in einer Richtung nicht skaliert werden, ist -1 einzutragen. <\/li>\n<li>public boolean checkAll()<br \/>\n    <br \/>\u00dcberpr\u00fcft, ob alle vom MediaTracker \u00fcberwachten Medien geladen worden sind. Falls der Ladeprozess noch nicht angesto\u00dfen wurde, wird dieser auch nicht initiiert. <\/li>\n<li>boolean checkAll( boolean load )<br \/>\n    <br \/>\u00dcberpr\u00fcft, ob alle vom MediaTracker \u00fcberwachten Medien geladen worden sind. Falls der Ladeprozess noch nicht angesto\u00dfen wurde, wird dieser dazu angeregt. <\/li>\n<li>boolean isErrorAny()<br \/>\n    <br \/>true, wenn eines der \u00fcberwachten Bilder einen Fehler beim Laden verursachte. <\/li>\n<li>Object[] getErrorsAny()<br \/>\n    <br \/>Liefert eine Liste aller Objekte, die einen Fehler aufweisen. null, wenn alle korrekt geladen wurden. <\/li>\n<li>void waitForAll() throws InterruptedException<br \/>\n    <br \/>Das Laden aller vom MediaTracker \u00fcberwachten Bilder wird angesto\u00dfen, und es wird so lange gewartet, bis alles geladen wurde oder ein Fehler beim Laden oder Skalieren auftritt. <\/li>\n<li>boolean waitForAll( long ms ) throws InterruptedException<br \/>\n    <br \/>Startet den Ladeprozess. Die Funktion kehrt erst dann zur\u00fcck, wenn alle Bilder geladen wurden oder die Zeit \u00fcberschritten wurde. true, wenn alle korrekt geladen wurden. <\/li>\n<li>int statusAll( boolean load )<br \/>\n    <br \/>Liefert einen mit Oder verkn\u00fcpften Wert der Flags LOADING, ABORTED, ERRORED und COMPLETE. Der Ladeprozess wird bei load auf true gestartet. <\/li>\n<li>boolean checkID( int id )<br \/>\n    <br \/>\u00dcberpr\u00fcft, ob alle Bilder, die mit der ID id verbunden sind, geladen wurden. Der Ladeprozess wird mit dieser Methode nicht angesto\u00dfen. Liefert true, wenn alle Bilder geladen sind oder ein Fehler auftrat. <\/li>\n<li>boolean checkID( int id, boolean load )<br \/>\n    <br \/>Wie checkID(id). Allerdings werden nur die Bilder geladen, die bisher noch nicht geladen wurden. <\/li>\n<li>boolean isErrorID( int id )<br \/>\n    <br \/>Liefert den Fehlerstatus von allen Bildern mit der ID id. true, wenn eines der Bilder beim Laden einen Fehler aufweist. <\/li>\n<li>Object[] getErrorsID( int id )<br \/>\n    <br \/>Liefert eine Liste aller Medien, die einen Fehler aufweisen. <\/li>\n<li>void waitForID( int id ) throws InterruptedException<br \/>\n    <br \/>Startet den Ladeprozess f\u00fcr 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. <\/li>\n<li>boolean waitForID( int id, long ms ) throws InterruptedException<br \/>\n    <br \/>Wie waitForID(), nur stoppt der Ladeprozess nach einer festen Anzahl von Millisekunden. <\/li>\n<li>int statusID( int id, boolean load )<br \/>\n    <br \/>Liefert einen mit Oder verkn\u00fcpften 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. <\/li>\n<li>void removeImage( Image image )<br \/>\n    <br \/>Entfernt ein Bild von der Liste der Medienelemente. Dabei werden alle Objekte, die sich nur in der Skalierung unterscheiden, entfernt. <\/li>\n<li>public void removeImage( Image image, int id )<br \/>\n    <br \/>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. <\/li>\n<li>public void removeImage( Image image, int id, int width, int height )<br \/>\n    <br \/>Entfernt ein Bild mit den vorgegebenen Ausma\u00dfen und der ID id von der Liste der Medienelemente. Doppelte Elemente werden ebenso gel\u00f6scht.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Der MediaTracker ist eine sehr alte Java-AWT-Klasse, bietet aber Dinge, \u00fcber die auch einfachere Bildlademethoden nicht verf\u00fcgen. 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 &#8211; so wie [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1],"tags":[],"class_list":["post-2252","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2252","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=2252"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2252\/revisions"}],"predecessor-version":[{"id":2253,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2252\/revisions\/2253"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=2252"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=2252"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=2252"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}