ここで使用する方法
ここでは、次のサンプルを使用しながら、説明していきます。
サンプル
難しいので、まずサンプルの説明から・・・。
public Sample_2()の手前にBufferStrategyとあります。
後ほど記述しますが、画面を置く倉庫のようなものだと思ってください。
次に24行目にjframe.setIgnoreRepaint(true);とあります。
これは画面の書き換え機能を切り替えています。深い意味は知らなくてもOKです。
次に25行目にjframe.createBufferStrategy(2);とあります。
これは画面を2枚用意するという意味の文です。アニメーションさせる場合は
画面のちらつきを防ぐため、実際に描画する画面とは別にもう1枚画面を用意します。
描画処理を画面に書いておいて、すべて書き終わった瞬間にその画面を表示させるのです。
それまでは別に用意した画面を表示させて起きます。これにより画面のちらつきを防げます
次に26行目にbstrategy = jframe.getBufferStrategy();とあります。これは意味を知らなくてもOKです。
次に27・28行目にTimer t = new Timer();、t.schedule(new MyTimerTask(),10,30);とあります。
これは描画処理を行う周期を設定しています。28行目が重要です。この文の意味は描画処理を
MyTimerTaskクラス内のrunメソッドに最初10ミリ秒遅らせた後、30ミリ秒ごとに行わせる
という意味の文です。このMyTimerTaskさんはTimerTaskクラスを引き継いでいる(継承)必要があります。
次に35行目にGraphics g = bstrategy.getDrawGraphics();とあります。これは
『bstrategyすなわち画面の倉庫のようなものから描画できる画面を受け取り、gに格納する』
という意味です。
次に36行目でif(bstrategy.contentsLost() == false){ とあります。これは
『受け取った画面が描画できる状態にあるか』という意味の文です。falseの場合使用可能という意味です。
次の37・38行目でInsets insets = jframe.getInsets();、g.translate(insets.left,insets.top);とあります。
これは描画位置を指定された値だけずらす処理です。描画の際、ウィンドウの大きさを含めた位置で指定しなければ
なりません。そこでウィンドウのタイトルバーの長さと左端の長さを取得しておき、あらかじめ位置をずらして
おきます。これにより正しい位置に描画できるようになります。
次の42行目でbstrategy.show();とあります。この文は描画した内容を表示するという文です。
次の43行目でg.dispose();とあります。この文は受け取った画面を返却するという意味です。
画面はさまざまなアプリケーションで使用するため、使い終わったら返さなければなりません。
そうしないとほかのアプリケーションに迷惑をかけることになります。
説明は長くなりましたが、このサンプルを使用して解説していきたいと思いますのでよろしくお願いします。
文字・図形の表示
ここでは文字・図形の表示方法を紹介します。やり方はアプレット講座で説明したメソッドを使用して
行います。ただその文を書き込む位置が違います。paintメソッドではなく、サンプルファイルの
"この間に描画したいない内容を記述。"の後に記述します。
実行してみます。うまく文字や図形が表示されましたか?
下にHELLOという文字列と四角を表示させるサンプルソースをおいておきますので参考にしてください。
サンプル
画像の表示方法
今度は画像の表示方法について説明します。画像の読み込み方法は残念ながら
アプレット講座のときに使用した方法と同じ方法は適用できません。
混乱するかもしれませんが、事実ですのでご了承ください。表示方法は同じです。
では画像の読み込み方法から説明します。サンプルをコピーし、まず、次のimport文を追加します。
import javax.imageio.*;
これは画像処理のためのクラス群です。これを用いると意外と簡単に読み込み出来ます。
次に"変数を宣言する"という部分に次の文を追加します。
BufferedImage testimage;
これは画像を格納する変数だと思ってください。
次にコンストラクタ内のTimer t = new Timer()という文の前に次の5行を追加します。
try{
testimage = ImageIO.read(getClass().getResource("test.jpg"));
}catch(IOException e){
}
ImageIO.read(getClass().getResource("test.jpg"));という部分がtest.jpgという名前の画像を読み込む処理です。
そして読み込んだ結果をtestimageが受け取ります。画像が読み込めないなど例外処理は、
下のcatch文で処理します。e.printStackTrace();は例外の内容を表示する処理です。
最後にMyTimerTaskクラスのrunメソッドに次の画像を表示させる文を記述します。
g.drawImage(testimage,100,100,jframe);
この文は画面(jframe)の座標(100,100)にtestimageを表示させるという意味の命令です。
今回使用した画像はしたのtest.jpgです。ダウンロードしてjavaファイルと同じフォルダに入れてお使いください。

test.jpg
コンパイルして実行してみてください。画像が表示されましたか?
サンプル
音をならす
今度は音をならす方法について説明します。音をならす方法は残念ながら
読み込み方法も鳴らす方法もアプレットで使った方法は適用できません。
しかも厄介なことに結構難しいわけです。難しい話は出来る限りカットしますので
頑張って試してみてください。
まずは次のimport文を追加します。
import javax.sound.sampled.*;
これは音を読み込むためのクラス群です。このクラスを使用することにより
音の加工、再生などさまざまなことが出来ます。ここでは音の再生に絞って
説明したいと思います。
次に"ここに変数を宣言する"の部分に次の2行を追加します。
AudioInputStream oto;
Clip clip = null;
AudioInputStreamは音の入力インタフェース(機構)を意味する変数です。
Clipは実際の音を格納する変数です。
次にコンストラクタ内のTimer t = new Timer()という文の前に次の12行を追加します。
try{
oto = AudioSystem.getAudioInputStream(getClass().getResource("decide3.wav"));
DataLine.Info info = new DataLine.Info(Clip.class,oto.getFormat());
clip = (Clip)AudioSystem.getLine(info);
clip.open(oto);
}catch(UnsupportedAudioFileException e){
}catch(IOException e){
}catch(LineUnavailableException e){
}
try文の中の4行から説明します。
まず、AudioSystem.getAudioInputStream(getClass().getResource("decide3.wav"));
ですが、これは画像を読み込むときと処理が似ています。まぁ意味も同じですが・・・。
これはdecide3.wavという音声ファイルを入力インタフェースであるotoに格納する変数です。
次に2行目のDataLine.Info info = new DataLine.Info(Clip.class,oto.getFormat());
ですが、これは読み込んだ音声ファイルの形式情報を取得する命令文です。
次に3行目のclip = (Clip)AudioSystem.getLine(info);ですが、取得した形式情報
をもとにClip変数に音声ファイルを格納する命令文です。
最後にClip変数に格納されている音声ファイルをオープンする命令文を
clip.open(oto);が行います。
最後にMyTimerTaskクラスのrunメソッドの中に次の文を追加します。
clip.start();
この文は読み込んだ音声データを再生させる文です。
今回使用した音声ファイルは下のdecide3.wavです。ダウンロードしてjavaファイルと同じフォルダに入れてお使いください。
decide3.wav
コンパイルして実行してみてください。画像が表示されましたか?
サンプル
マウス操作を加える
ここではマウス操作を加える方法を説明します。アプレット時に使用した方法でもいいのですが、
ここではもっと便利な方法を説明します。今回はマウスボタンを画面内で押したときには"押された"
という文字を表示し、画面内で離した時は"離された"と表示するアプリケーションを作成します。
サンプルを使用し、まず"ここに変数を宣言する"部分に次の2文を追加します。
boolean press = false;
boolean release = false;
これはマウスボタンが押されたか、あるいは離されたかをそれぞれ判定する変数です。
次にpublic class〜内に次のclassを追加します。
class MyMouseAdapter extends MouseAdapter{
public void mousePressed(MouseEvent e){
press = true;
release = false;
}
public void mouseReleased(MouseEvent e){
press = false;
release = true;
}
}
新たなクラスMyMouseAdapterを作成します。マウス操作についてまとめられているクラス
MouseAdapterを継承することによって、マウス操作の記述を容易にします。
*mousePressedメソッドとmouseReleasedメソッドについてはアプレット講座で説明しているので
*ここでは省略します。
マウスボタンが押されたときに、変数press(マウスボタンが押されたか判定する)をtrueにし、変数release
(マウスボタンが離されたか判定する)をfalseにします。マウスボタンが離されたときは押されたときと
変数代入を逆転させます。(true→false,false→true)
次にコンストラクタ内のTimer t = new Timer()という文の前に次の1文を追加します。
jframe.addMouseListener(new MyMouseAdapter());
これは画面にマウスリスナーを追加するという意味の命令文です。どのように動作させるかというのを
第1引数で指定します。ここではnew MyMouseAdapter()とし、MyMouseAdapterクラスに記述されている
内容を元に動作させると命令しています。
最後にMyTimerTaskクラスのrunメソッドの"この間に描画したい内容を記述。"の部分に
次のように記述します。
if(press){
g.drawString("押された",100,100);
}
if(release){
g.drawString("離された",100,100);
}
pressがtrueのときは押されているときなので、押されたという文字を表示します。また、releaseがtrue
のときは離されているときなので、離されたという文字を表示します。
実行してみます。うまく動作しますか?
サンプル
キーボード操作を加える
ここではキーボード操作を加える方法を説明します。アプレット時に使用した方法でもいいのですが、
ここではもっと便利な方法を説明します。今回はキーを画面内で押したときには"押された"
という文字を表示し、画面内で離した時は"離された"と表示するアプリケーションを作成します。
サンプルを使用し、まず"ここに変数を宣言する"部分に次の2文を追加します。
boolean press = false;
boolean release = false;
これはキーが押されたか、あるいは離されたかをそれぞれ判定する変数です。
次にpublic class〜内に次のclassを追加します。
class MyKeyAdapter extends KeyAdapter{
public void keyPressed(KeyEvent e){
press = true;
release = false;
}
public void keyReleased(KeyEvent e){
press = false;
release = true;
}
}
新たなクラスMykeyAdapterを作成します。キーボード操作についてまとめられているクラス
KeyAdapterを継承することによって、キーボード操作の記述を容易にします。
*keyPressedメソッドとkeyReleasedメソッドについてはアプレット講座で説明しているので
*ここでは省略します。
キーが押されたときに、変数press(キーが押されたか判定する)をtrueにし、変数release
(キーが離されたか判定する)をfalseにします。キーが離されたときは押されたときと
変数代入を逆転させます。(true→false,false→true)
次にコンストラクタ内のTimer t = new Timer()という文の前に次の1文を追加します。
jframe.addKeyListener(new MyKeyAdapter());
これは画面にキーボードリスナーを追加するという意味の命令文です。どのように動作させるかというのを
第1引数で指定します。ここではnew MyKeyAdapter()とし、MyKeyAdapterクラスに記述されている
内容を元に動作させると命令しています。
最後にMyTimerTaskクラスのrunメソッドの"この間に描画したい内容を記述。"の部分に
次のように記述します。
if(press){
g.drawString("押された",100,100);
}
if(release){
g.drawString("離された",100,100);
}
pressがtrueのときは押されているときなので、押されたという文字を表示します。また、releaseがtrue
のときは離されているときなので、離されたという文字を表示します。
実行してみます。うまく動作しますか?
サンプル
アニメーションさせる
最後にアニメーションさせる方法を紹介します。といってもほとんど紹介してしまったようなものです。
では円(幅、高さ20)をx座標100〜200の間で左右に動かす(30ミリ秒ごとにx座標を1動かす。x座標が両端まで
達したら、移動方向を逆転させる。スタート位置は100,y座標は常に50)アプリケーションを作成しましょう。
サンプルを使用し、まず"ここに変数を宣言する"部分に次の1文を追加します。
int circle_x = 100;
int dx = 1;
circle_xは円のx座標を格納する変数です。初期値は100ですので100を格納しておきます。
dxはx座標の増分を示す変数です。右に動かす場合は1、左に動かす場合は-1を格納しておきます。
初期値は右に動かすので1をセットします。
次にMyTimerTaskクラスのrunメソッドの"ここに描画したい内容を記述"の部分に次の8文を追加します。
circle_x = circle_x + dx;
if(circle_x == 200){
}
if(circle_x == 100){
}
g.drawOval(circle_x,50,20,20);
最初のcircle_x = circle_x + dx;で円のx座標を1移動させます。そして次の文
if(circle_x == 200){でx座標が右端に達したかを判定しています。右端に達していたら
移動させる方向を左方向に変換させます。dx = -1;はそのための処理です。
同様に次の文if(circle_x == 100){でx座標が左端に達したかを判定しています。
左端に達していたら移動させる方向を右方向に変換させます。dx = 1;はそのための処理です。
実行してみます。うまく動作しますか?
サンプル