イメージロード

アプレット

imgbak = javax.imageio.ImageIO.read(
                 new java.io.File("testsprite/aqua00.jpg"));
のよう読み取り方法はアプレットで使えません。
また、イメージの読み取り処理が完結しないくても、リターンする場合があります。
コンポーネントに使う場合に問題ありませんが、 この完結していないImageオブジェクトをdrawImageメソッドで使うと失敗します。
そこで、完全にイメージの読み取りが終わるまで待つ必要があります。
以下ではそれを考慮し、MediaTrackerクラスを利用しています。 しかもアプレットやリソースからの読み取りも可能なToolkitのgetImageメソッドを使っています。

//イメージファイルを読み取るユーティリティクラス

package sprite;//パッケージ名
import java.awt.image.*;//BufferedImage,ImageObserverなど用
import java.awt.*;//Graphicsなど用
public class ImgUtil{
	//引数ファイル名の画像のイメージを返します。(ファイル名の位置はobserverのクラスと同じ位置)
	public static Image getImageBy(String fileName, Component observer){
		java.net.URL url = null;
		Image img = null;
		java.awt.MediaTracker tracker = null;
		try{
			url = observer.getClass().getResource(fileName);
			if (url == null){
				throw new Exception("リソースが見つかりません:" + fileName);
			}
			img = observer.getToolkit().getImage(url);
			tracker = new java.awt.MediaTracker(observer);//イメージの呼び出しを監視
			tracker.addImage(img, 0);//監視リストに追加
			tracker.waitForID(0, 20000);//イメージ読み込みが完了するまで最大20秒待つ。
			int status = tracker.statusID(0, false);
			if (status != java.awt.MediaTracker.COMPLETE){
				throw new Exception("イメージ画像取得に失敗:" + fileName);
			}
		}
		catch (Exception e)	{
			javax.swing.JOptionPane.showMessageDialog(observer, e.toString(),
				"イメージ画像取得に失敗", javax.swing.JOptionPane.ERROR_MESSAGE);
		}
		return img;
	}
	
	//引数ファイル名の変更可能なイメージを返します。(ファイル名の位置はobserverのクラスと同じ位置)
	public static BufferedImage getImageBy(Image img, Component observer){
		BufferedImage imgRtn = null;
		int width = img.getWidth(observer);
		int height = img.getHeight(observer);
		imgRtn = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
		Graphics g = imgRtn.getGraphics();
		g.drawImage(img, 0, 0, observer);
		return imgRtn;
	}
}

2つstaticメソッドが用意されていますが、Imageを返す方が編集できないImageを返します。 これは、gifアニメーションファイルにも対応しています。
ファイル名 と監視オブジェクトを指定します。監視オブジェクトは描画対象のコンポーネントを指定しますが 同時に、そのクラスのロード位置(ディレクトリ)が、読み取るファイル位置で、 ファイル名は、この位置を基準とした相対パスを指定できます。
もう一方は、引数のImageから編集可能なBufferedImageを取得するメソッドで、イメージ複製にも使えます。
以下で、前回の作品を、これを使う方法に 変更したアプレット版例を示します。 (フレーム版でも使えます)

package testsprite;
import sprite.*;//Sprite,SpriteBasic,SpriteThreadのパッケージ
import java.awt.*;//Imageなどのパッケージ
import javax.swing.*;//JPanel,JFrameなどのパッケージ

public class TestSprite1 extends JApplet//アプレットクラス
{
	MainPanel panel;//上記のパネル
	
	public void init(){//start前に呼び出されます(ダウンロードが完了時)。
		this.setContentPane(panel = new MainPanel());
	}

	public void stop(){//webブラウザから、閉じる時、ブラウザからよびだされる命令
		this.panel.spriteThread.stop();//描画スレッド停止
	}
}

//メインパネル
class MainPanel extends JPanel {
	static MainPanel main;	//この作品のパネル(グローバル変数のように扱える)
	
	static Image imgbak;	//背景素材イメージ
	static Image img1;	//素材1イメージ
	static Image img2;	//素材2イメージ

	SpriteThread spriteThread;	// 描画、アニメーションスレッド

	SpriteBasic spriteBak;//背景管理用
	SpriteBasic sprite1;//素材1
	SpriteBasic sprite2;//素材2

	MainPanel() {//コンストラクタ
		MainPanel.main = this;
		//素材画像ファイル読み取り
		imgbak = ImgUtil.getImageBy("aqua00.jpg", this);//背景
		img1 = ImgUtil.getImageBy("sanma00.gif", this);//素材1イメージ

		//スレッド初期化、描画対象(panel)の設定とイメージサイズ指定
		int w = imgbak.getWidth(this);//背景画像サイズ取得
		int h = imgbak.getHeight(this);
		spriteThread = new SpriteThread(w, h, this); //描画対象をpanelとして、背景画像サイズに合わせる

		spriteThread.add( new SpriteBasic(bg) );//背景を追加
		spriteThread.add( new SpriteBasic(ch) );//魚追加

		spriteThread.subSprite.get(1).x=10;//2番目に追加したSpriteの位置を変更
		spriteThread.subSprite.get(1).y=100;

		spriteThread.start(10);//0.01秒のアクションスレッド スタート	
	}

	public void paintComponent(Graphics g){//上記スレッド起動時の間隔(0.01秒)で呼び出される。
		super.paintComponent(g);
		if (spriteThread != null) spriteThread.paintTo(g);
	}
}

リソースの画像を利用する。

Imageを取得する場合に、Fileを使う方法があります
ImageIO.read(new File("ファイルパス"));
他に、上記でも示した ImageIO.read(ファイルのURL); の方法は、 後述する実行可能ファイルにパッケージ化されたファイル内から取得する場合に使います。
eJ1804m0.htmで行った次の記述で比較する。
Image bg;//背景素材イメージ
Image ch;//素材1イメージ
try{
	bg = ImageIO.read(new File("aqua00.jpg"));//背景素材イメージ
	ch = ImageIO.read(new File("sanma00.gif"));//素材1イメージ
catch(Exception e){
	e.printStackTrace();
}
以上をリソース扱いで取得すると、次のようにできます。
Image bg;//背景素材イメージ
Image ch;//素材1イメージ
try{
	bg = ImageIO.read(this.getClass().getResource("aqua00.jpg"));//背景素材イメージ
	ch = ImageIO.read(this.getClass().getResource("sanma00.gif"));//素材1イメージ
catch(Exception e){
	e.printStackTrace();
}
クラス変数の場合はstaticイニシャライザを使います。TestSplitePanel1クラスのstatic変数であれば、次のようにできます。
static Image bg;//背景素材イメージ
static Image ch;//素材1イメージ
static {
	try{
		bg = ImageIO.read(TestSplitePanel1.class.getResource("aqua00.jpg"));//背景素材イメージ
		ch = ImageIO.read(TestSplitePanel1.class.getResource("sanma00.gif"));//素材1イメージ
	}
	catch(Exception e){
		e.printStackTrace();
	}
}

このspariteパッケージのライブラリを使う作品のjarを作るバッチファイル例を、参考に示します。
JDKのインストール環境によって変更する箇所はこの色で、
作品ごとに変更する箇所はこの色です。 この実行によって、test.jarのファイルを作成します。

rem ==== fish_shooting.jar を作る。==========
echo 作品のソースのルーパス(開発位置でもある)にセット
set srcpath=.
cd %srcpath%

echo mainがあるクラスパッケージ名指定
set pack=fishgame

echo mainがあるクラスの名指定
set src=TestSplitePanel1

echo 作成する実行可能ファイル名指定
set mkfile=test.jar

echo javaの開発ツール位置設定
set JAVAHOME=H:\jdk1.7.0_80

echo 開発用環境変数設定
set path=%JAVAHOME%\bin;%path%
set CLASSPATH=.;sprite.jar;%JAVAHOME%;

echo jar作業ディレクトリ作成(ここにクラスを作り、リソースを集める)
set temp=WORK
mkdir %temp%

javac -d %temp% -encoding windows-31j -source 1.6 -target 1.6 %pack%\%src%.java
echo コンパイル判定
IF ERRORLEVEL 1 GOTO LEND

echo マニフェストファイル作成
echo Main-Class: %pack%.%src%> %temp%\manifest.txt
echo Class-Path: %src%.jar .>> %temp%\manifest.txt

echo 必要なファイルを作業ディレクトリにコピー
copy %pack%\*.css %temp%\%pack%
copy %pack%\*.gif %temp%\%pack%
copy %pack%\*.png %temp%\%pack%
copy %pack%\*.jpg %temp%\%pack%
copy %pack%\*.mid %temp%\%pack%
copy %pack%\*.wav %temp%\%pack%
PUSHD %temp%
jar -fx R:\pleiades\workspace\game28\sprite.jar
POPD

echo jarで圧縮ファイルを作成
jar cmvf %temp%/manifest.txt %mkfile% -C %temp%/. .

:LEND
rem  %temp%ディレクトリを削除します。
rmdir %temp% /S /Q

echo jarの実行
java -jar %mkfile%
cmd