画像の追跡
画像の読み込みに同期をとる
AWTによるイメージの取得、読み込みや操作など
画像に関する操作の多くはほとんどが非同期です
このメリットは、画像の読み込みを行っている間でも
プログラムは次の処理に進むことができ、その作業をプログラマが意識しなくてよいことです
とくに、画像の読み込みに時間がかかるネットワークアプレットでは、この機能は重要です
画像を読み込んでいる間の数10秒間、操作ができなければ非常に困りますね
しかし、この非同期による読み込みには弱点もあります
以前やりましたが、たとえば画像を読み込んでから画面にイメージを表示させたい場合や
イメージを全て読み込んでから、次の処理に進ませたい場合などです
以前は、Componentクラスの(正確にはImageObserverの)imageUpdate()を用いて
画像の読み込みを監視することで、その動作を実現させることができました
ですがその作業は面倒です
imageUpdate()が追跡するデータに興味がなく
画像の読み込みに同期をとりたいだけの場合はjava.awt.MediaTrackerクラスを使用します
このクラスは画像のロードを追跡することができます。以下はコンストラクタです
public MediaTracker( Component comp )
compには、イメージが描画されるコンポーネントを指定します
ここで生成したオブジェクトに、イメージを登録する必要があります
MediaTrackerでは、イメージをID番号で扱います
イメージの登録、追加にはaddImage()メソッドを使用します
public void addImage( Image image, int id )
public synchronized void addImage( Image image, int id, int w, int h )
imageには、登録するイメージのオブジェクトを
idには、イメージを扱うためのIDを指定します
このIDはMediaTrackerクラスのメソッドでイメージを操作するための情報になります
wには幅、hには高さを指定しイメージをスケーリングします
画像のロードを開始するにはwaitForID()メソッドを
またはwaitForAll()メソッドを使用します
public void waitForID( int id ) throws InterruptedException
public synchronized boolean waitForID( int id, long ms ) throws InterruptedException
public void waitForAll() throws InterruptedException
public synchronized boolean waitForAll( long ms ) throws InterruptedException
idには、ロードするidを指定します
msにはロードを完了するまでの待機時間(ミリ秒)で、これを指定した場合は
読み込みが終了するか、指定時間が経過するまで画像を読み込みます
時間を指定するメソッドはboolean型の戻り値で、画像が読み込まれたかどうかを返します
正常にロードされればtrueを、それ以外の場合はfalseを返します
waitForAll()メソッドは、トラッキングしている全てのイメージをロードします
読み込みは、IDの低位番号を優先に行われ
イメージのロード中またはスケーリング中にエラーが発生すると、そのイメージのロードは完了したと見なされます
import java.applet.Applet;
import java.awt.*;
/* <applet code="test.class" width="300"height="300">
<param name="img" value="img/test.jpg">
</applet>
*/
public class test extends Applet {
Image img;
public void init() {
MediaTracker mt = new MediaTracker(this);
img = getImage(getDocumentBase() , getParameter("img"));
mt.addImage(img , 0 , 200 , 200);
try { mt.waitForID(0); }
catch(InterruptedException e) { }
}
public void paint(Graphics g) {
System.out.println("width = " +
img.getWidth(this) + " height = " + img.getHeight(this));
g.drawImage(img , 0 , 0 , this);
}
}
このアプレットは、init()メソッドが起動時に実行され
waitForID()によって、画像を読み込むまで待機します
paint()メソッドが実行されるのは、画像のロードが終了してからになります
この機能は、たとえば読み込まれた画像のサイズに合わせてウィンドウサイズを決定する場合
画像の読み込み途中でImage.Width()やImage.Height()を実行すると -1 を返すので
このように、画像のロードを待機する必要があるのです
トラッキングしているIDが、画像のロードを終了しているかどうかを確認するには
同クラスのcheckID()メソッドで調べることができます
また、トラッキングしている全ての画像を調べるにはcheckAll()を使用します
public boolean checkID( int id )
public boolean checkID( int id, boolean load )
public boolean checkAll()
public boolean checkAll( boolean load )
idには、調べるIDを指定し
loadをtrueにした場合、画像がまだ読み込まれていなかったとき、ロードを開始します
画像がロード(あるいはエラーか中断)されていればture、そうでなければfalse()を返します
エラーの監視にはisErrorID()またはisErrorAny()を使用します
ロード中にエラーが発生すると、ロードが完了されてしまうため、エラーチェックの対策に用います
public synchronized boolean isErrorID( int id )
public synchronized boolean isErrorAny()
isErrorID()はidに調べるIDを指定し、識別子を持つイメージにエラーがあればtrueを
isErrorAny()は、トラッキングしているリストの中にエラーがあればtrueを返し
いずれもエラーがなければfalseを返します