画面全体の色が変化していくだけのアプレットです。明るい色から徐々に暗い色に変って、それをもう一度繰り返してから、別の色に変ります。これを作っていく過程を順に説明します。第1部の8章で示した基本的なアプレットのソースから進めていきます。 |
第1部の8章で示したアプレットのソースは次のような物でした。
import java.applet.Applet; import java.awt.*; public class Test100 extends Applet { public void paint(Graphics g) { g.setColor(Color.red); g.drawLine(5,5, 5,95); g.drawString("Javaアプレット", 20, 20); } }このアプレットでは画面に1本の線と"Javaアプレット"という文字列を表示しました。paintメソッドの中で線と文字列を表示しました。今度のアプレットは画面には線も文字も出ませんが、画面全体の色が変化していきます。paintの中で画面の色を少しずつ変えながらループさせれば出来るのでしょうか。こんな感じです。 import java.applet.Applet; import java.awt.*; public class Test200 extends Applet { public void paint(Graphics g) { while(true) { 新しい色を作る; g.setColor(newColor); g.fillRect(0, 0, 200, 200); } } }whileでループするには、while(true) とします。while文はwhileに続く括弧の中が評価され、それがtrueの場合のみ次の文が実行されます。文は{と}で囲まれた部分で、whileの評価がfalseになるまで繰り返します。括弧の中にtrueと書いておけば永久に繰り返します。 ループの中では新しい色を作って変数newColorに入れ、それを現在の色としてセットし、fillRectで画面全体を塗りつぶします。新しい色を作るところさえ作ればうまくいきそうですが、このやり方はJava風ではないようです。 |
動きのあるアプレットを作る場合のJavaの書き方というのがあります。スレッドという物を使います。
スレッドとは処理を平行動作させる時のひとつひとつの処理の事を言うようです。スレッドを使うと、動きのあるアプレットの処理が簡単になります。実際には今回の例よりも高度な処理をする場合に力を発揮するようです。 処理をスレッドにするにはクラスの宣言でRunnableインターフェースを実装します。具体的には次のように書きます。 public class Test200 extends Applet implements Runnable {implements RunnableがRunnableインターフェースの実装を意味しています。これで、Test200クラスが平行処理されるスレッドのひとつになります。処理の実際はTest200クラスのrunメソッドに記述します。さらに別のスレッドを使いたければ、Runnableクラスを実装した別のクラスを作り、そのrunメソッドにその処理を記述します。runメソッドの中には(たぶん)必ず処理を一定時間停止させるsleepメソッドが使われ、その時間に別のスレッドの処理が行なわれ、人間から見ると同時に処理されている様に見えます。 |
ここで少し寄り道してインターフェースについて説明します。インターフェースはクラスに似ています。クラスはメソッドを持ち、各メソッドは機能が定義されていますが、インターフェースのメソッドは宣言しか持ちません。インターフェースの持つメソッドの機能はインターフェースを実装した各クラスに書きます。クラスの指定に“implements インターフェース名”で実装を宣言します。同じ名前で同じ型のメソッドが幾つかのクラスに存在する場合が出てきますが、これらのメソッドをインターフェースを通じてひとつのメソッドのように処理する事が出来ます。それがインターフェースの役割です。上記のRunnableインターフェースでは、Runnableインターフェースを実装したThreadクラスの中で、中身の違うであろうrunメソッドがひとつの物として処理されています。 『同じ名前で同じ型のメソッドが幾つかのクラスに存在する場合が出てきますが、これらのメソッドをインターフェースを通じてひとつのメソッドのように処理する事が出来ます。それがインターフェースの役割です。』 この文の意味が分かりにくいと思いますが、内容も違っているようです。インターフェースを使わなくても同じ名前で同じ型のメソッドを複数のクラスに定義できます。その同じ名前で同じ型のメソッドに何らかの関連がある場合にインターフェースを使うといい場合があるという事です。 スレッドを使うには、Runnableインターフェースを実装する以外に、Threadクラスを継承するという方法もあります。ThreadクラスはRunnableインターフェースを実装しているので、直接Runnableインターフェースを実装するのと同じになるのでしょう。ただし、Javaは単一継承といって、クラスが直接継承できるクラスがひとつしかありません。アプレットはAppletクラスを継承しているので他のクラスはもう継承できないのでRunnableインターフェースを実装する方法を使います。 |
それでは、スレッドの使い方を調べながら、実際のプログラムを見ていきます。第1部の8章で基本的なアプレットがどんなメソッドを利用して動いているかを書きました。振り返って見ます、initメソッドはブラウザによって最初に呼び出され、変数の初期化をします。前のもっとも簡単なアプレットでは使いませんでしたが、今回は必要になるかも知れません。startメソッドはinitの後と、アプレットのHTML文が表示されるごとに呼び出されます。stopメソッドはブラウザがアプレットを含む HTML文を終了するとき呼び出されます。start,stopも前の例では使いませんでしたが、今度はスレッドを実行するのと止めるのに使用します。paintメソッドは最初の表示と、ウィンドウが重なって隠されていた表示の修復に呼ばれます。今度もまた表示関係を記述します。runメソッドはスレッドで実行される処理を書きます。 今回はinitやstartメソッドを書くのでjava.applet.Appletクラスの各メソッドの説明を見てみると、 init() ブラウザまたはアプレットビューワによって呼び出され、……。 start() ブラウザまたはアプレットビューワによって呼び出され、……。 stop() ブラウザまたはアプレットビューワによって呼び出され、……。 となっています。ブラウザがinitを呼び出し、その後startを呼び出すようです。アプレットの終了時にはstopを呼び出すようです。paintもコンポーネントが最初に表示されるときやダメージの回復が必要なときなどにブラウザが呼び出すようです。解説書を良く読んでみると、initからstartへの処理とpaintなどの表示関係の処理はブラウザの別のスレッドとして動いているそうです。 では、ここまでの概略をプログラムの形にしておきます。 import java.applet.Applet; import java.awt.*; public class Test200 extends Applet implements Runnable { Color newColor; public void init() { // 初期化 } public void start() { // スレッドを実行 } public void stop() { // スレッドを止める } public void run() { while(true) { 新しい色を作る; repaint(); // repaintはupdateを呼び、updateはpaintを呼ぶ } } public void paint(Graphics g) { g.setColor(newColor); // 色のセット g.fillRect(0, 0, 200, 200); // 画面を塗る } } |