!!! 第二章 初めてのアプレット !! 2-1. 「動くアプレット」のテンプレート まずは、動く物理アプレットのテンプレート(ひな形)を提示します。このテンプレートを利用すれば、誰にでも簡単に動く物理アプレットが作れてしまいます! テンプレートは次のとおりです。 ''AppletTemplate.java'' {{pre num import java.applet.*; import java.awt.*; /* * 最も基本的な、動くアプレットのテンプレートです。 * * */ /** * @author Osamu Koizumi * */ public class AppletTemplate extends Applet implements Runnable{ /** スレッド */ Thread th; /** 経過時間を保持する変数 */ double t = 0; /** 時間の刻み (ミリ秒単位) */ int dt = 100; /* * このメソッドには初期化処理を記述します。 * @see java.applet.Applet#init() */ public void init(){ } /* * アプレットの実行が始まると呼ばれます。 * @see java.applet.Applet#init() */ public void start(){ // おまじない if( th == null){ th = new Thread( this); th.start(); } } /* * このメソッドには反復処理を記述します。 * @see java.lang.Runnable#run() */ public void run(){ while( th != null){ /* * ここに計算などの処理を記述します。 */ // 計算結果を画面に反映させるために再描画する repaint(); // 時間を進める (dt を秒単位に直すために1000で割る) t = t + dt/1000.0; // 刻み時間だけ待つ try{ Thread.sleep( dt); } catch( InterruptedException ex){ } } } public void paint( Graphics g){ /* * ここに描画処理を記述します。 */ } /* * アプレット停止時に呼ばれます。 * @see java.applet.Applet#stop() */ public void stop(){ th = null; } } }} どうですか?意外に短いプログラムソースだと思いませんか。 ! テンプレートプログラムの流れ 簡単に、テンプレートプログラムの流れを説明しておきます。図15を見てください。 {{ref_image fig015.png}} '''図15''' テンプレート・プログラムの流れ まずはじめに、プログラム自体が起動されます。 プログラムが起動されると、最初に初期化処理というものを行います。変数の初期値を代入したりといった処理です。初期化が終わると、あとは計算と描画の繰り返しになります。 実際のコードについても、ひとつひとつ解説しておくことにしましょう。ここで書くことをいちいち全て覚えておく必要はありません。気になったときに「ここはどうなってるんだろうなぁ?」と見返してもらえば良いです。 1.import java.applet.*; 2.import java.awt.*; 1,2行目の import 〜 という文は、アプレットを作るのに必要な部品を取り込むための命令です。C言語でプログラムを組んだことのある人ならば、#include 命令を思い出すことでしょう。あれと同じことです。 4./* 5. * 最も基本的な、動くアプレットのテンプレートです。 6. * 7. * 8. */ 4行目から13行目まではコメントですね。コメントについて忘れてしまった方は20ページを読み返してみてください。以降、コメントについては特に言及しません。 14行目はこれから作成するクラスについて定義しています。 14.public class AppletTemplate extends Applet implements Runnable Appletクラスを継承し、Runnable インタフェースを実装することを宣言しています。Runnable インタフェースを実装したので我々は run() というメソッドを実装してやらなければなりません。それは45行目以降で行っています。クラスの継承やインタフェースについて忘れてしまった場合は25ページあたりを読み直してみて下さい。 つづいて15,16行目です。 15. /** スレッド */ 16. Thread th; 16行目ではThreadというクラス変数を定義しています。スレッドはアプレット内に時計をひとつ置くのだと思ってください。ただしこの時点ではまだ時計のオブジェクトは作成されていないので、時計はスタートしていません。 17. /** 経過時間を保持する変数 */ 18. double t = 0; 19. /** 時間の刻み (ミリ秒単位) */ 20. int dt = 100; 18,20行目はそれぞれ経過時間を保持するdouble型の変数tと、時間の刻みを保持するint型の変数dt を宣言しています。ひとつ注意しておかなければいけないのは、dtをミリ秒(1秒の1000分の1)単位で定義しているということです。これを秒単位で定義することもできますが、その場合にはdouble型で定義しなおす必要があります。 26. public void init(){ 27. } 26,27行目ではinitというメソッドを定義しています。正確に言うならば、initメソッドをオーバーライドしています。このinitメソッドは、アプレットがビューアやブラウザなどによってロードされると実行されます。このメソッドは後述するstartメソッドよりも先に呼ばれます。このメソッド中には初期化処理を記述すると良いでしょう。 33. public void start(){ 34. // おまじない 35. if( th == null){ 36. th = new Thread( this); 37. th.start(); 38. } 39. } 33行目から39行目はstartメソッドを定義しています。こちらも正確に言えばオーバーライドしています。このstartメソッド中には「おまじない」とかコメントが書いてある処理が置かれていますね。何をやっているのか気になっちゃう人もいると思うので簡単に解説しておきます。先ほど、16行目でThreadクラスのクラス変数を定義しました。これは「時計をひとつ用意した」といいました。ここではその時計クラスのオブジェクトを生成して、その時計のスタートボタンを押してスタートさせたのだと考えてもらうと良いと思います。 上述したinitメソッドとstartメソッドが、図15の「初期化」処理に相当します。 45. public void run(){ 46. while( th != null){ 47. /* 48. * ここに計算などの処理を記述します。 49. */ 50. 51. // 計算結果を画面に反映させるために再描画する 52. repaint(); 53. 54. // 時間を進める (dt を秒単位に直すために1000で割る) 55. t = t + dt/1000.0; 56. 57. // 刻み時間だけ待つ 58. try{ 59. Thread.sleep( dt); 60. } 61. catch( InterruptedException ex){ 62. } 63. } 64. } 45行目から64行目のrunメソッド内、while文の中身が、図15の反復部分「計算→描画→...」になります。runメソッドはRunnableインタフェースで定義されているメソッドです。50行目の「ここに計算などの処理を記述します」とコメントされている部分に、時刻tにおける位置座標などの値を計算するための式を記述します。それらの値を計算し終わったら、52行目でrepaint()という命令を呼び出し、描画画面を更新させています。描画画面を更新したのち、55行目で時間をdtだけ進めて、58行目から62行目の処理で実際にその時間が経過するのを待たせています。 前述のrunメソッド内で、repaintというメソッドを呼び出しています。これは画面の再描画を命令しているメソッドなのですが、最終的には66行目から70行目のpaintメソッドが呼ばれることになります。したがって、描画の処理はこのpaintメソッドの中に記述しておけば良いことになります。 ! 書き加えるべき部分 我々が実際に動く物理アプレットを作るとき、テンプレートに書き加えるべきものは次の二つです。 計算処理 (runメソッド中、46行目あたり) 描画処理 (paint メソッド中、67行目あたり) このテンプレートを用いた具体例を、等速円運動を例にとって見ていくことにしましょう。