2.1 アプレット・プログラミング
2.1.1 ブラウザとアプレット
アプレットとは、Java のオブジェクト指向と卓越した技術概念を生かした重要な技術であり、Java を世界に知らしめることになったキラーソフトウェアもアプレットで作られていました。アプレットは Java 言語と標準ライブラリを使った GUI アプリケーション開発のヒントとなるため、今後 GUI アプリケーションの開発方法を解説する上でアプレットを使います。
現代の GUI システムの代表的存在である Windows や Macintosh はオブジェクト指向のエキスパートであるアラン・ケイ博士がパロアルト研究所で開発したアルトと呼ばれるシステムを原型としています。アプリケーションを起動するとウィンドウと呼ばれる個々のアプリケーションがユーザーと対話するためのグラフィカルな矩形が描画され、プログラムはウィンドウ内に必要な情報を表示したり、ユーザーが操作するための部品を配置します。この基本的な考え方は Windows も Macintosh も X Window も同じなので、同一の Java クラスファイルで同じ動作を行うことは難しいことではありません。
アプレットはこのうち、プログラムのメインウィンドウを省略して、ソフトウェアの作業領域だけを記述することで他のアプリケーションに組み込むことができるプログラムのことです。作業領域を表示するウィンドウを抽象化することで、様々な場所や他のソフトウェアの部品として実行することができるため、アプレットはブラウザで実行することができ、インターネット上で高度なソフトウェアを HTML ファイルに埋め込む手段として注目されました。例えばブラウザで表示する場合、アプレットのコンテナ(アプレットを表示する親ウィンドウ)はブラウザが表示している HTML ドキュメントということになります。理論上、アプレット表示するのはブラウザ以外でもかまいません。実装では、アプレットをデバッグするためのアプレットビューワが存在します。アプレットビューワでアプレットを実行するときは、アプレットビューワがアプレットのコンテナということになります。どちらで表示するにせよ、アプレットには関係ありません。アプレットは作業領域だけを定義し、ユーザーにサービスを提供することだけを考えればよいのです。
ただし、ブラウザなどのネットワーク上の他のコンピュータからダウンロードした Java プログラムがアプレットによって自動的に実行されると、セキュリティの問題も発生してしまいます。知らないプログラムにファイルを操作されることは危険です。そこで、アプレットではファイル入出力処理ができないように設計されています。
アプレットのプログラムでは main() 関数は必須ではありません(あってもかまいません)。アプレットを作るには、まず java.applet.Applet クラスを継承しなければなりません。正確には、このクラスそのものをアプレットと呼びます。すべてのアプレットプログラムはこのクラスを継承していなければならないのです。
java.lang.Object | +--java.awt.Component | +--java.awt.Container | +--java.awt.Panel | +--java.applet.Applet
public class Applet extends Panel
Applet クラスはいくつかのクラスを継承していますが、これらのクラスは GUI アプリケーションの開発の最も基本となるクラス群であり、非常に重要です。Applet に到達するまでの Component、Container、Panel クラスについては今後詳しく説明するので、この場では Applet クラスに注目します。
私たちは、この Applet クラスを継承し、Applet クラスが提供するメソッドをオーバーライドすることでプログラムを独自に拡張することができます。アプレットが読み込まれると init() メソッドが呼び出されるので、このメソッドがアプレットにおける main() 関数のような存在です。そして、アプレットがメモリから解放されると destory() メソッドが呼び出されます。また、アプレットが開始すると start() メソッドが、中断すると stop() メソッドがコンテナから呼び出されます。
public void init()
public void destroy()
public void start()
public void stop()
これらのメソッドをオーバーライドすることで、アプレットを初期化したり、実行に備えた準備を行うことができます。アプレットの中断とは、アプレットがメモリに常駐するものの、画面から外されるなどの状態を表します。例えば、アプレットビューワではウィンドウを最小化したときに stop() メソッドが呼び出されます。
public class Test extends java.applet.Applet { public void init() { ... } public void start() { ... } public void stop() { ... } public void destroy() { ... } }
これが、アプレットの基本的な実装方法となるでしょう。もちろん、初期化や解放処理が必要なければ無理にオーバーライドする必要はありません。Applet クラスのこれらのメソッドは何もしていないので、スーパークラスのメソッドをサブクラスのオーバーライドしたメソッドから呼び出す必要はありません。
アプレットを実行するには、アプレットビューワかブラウザを使います。通常は、アプレットのデバッグや動作確認を行うのにアプレットビューワを使い、ネット上で配信するときにブラウザで表示させます。もちろんブラウザはアプレットに対応したブラウザでなければなりません。アプレットを HTML ドキュメントに貼り付けるには applet 要素を指定します。
<applet code="クラスファイル名" width="幅" height="高さ"> ... </applet>
applet 要素には必須属性としてクラスファイル名を指定する code、幅と高さを表す width と height 属性を指定しなければなりません。applet 要素の本体にはアプレットにパラメータを渡す param 要素を指定することができます。
JDK には appletviewer.exe というアプレットを実行するアプレットビューワが付属しています。アプレットビューワでアプレットを実行するには、アプレットが組み込まれている HTML ファイルを引数にして起動しなければなりません。
>appletviewer ファイル名
ただし、アプレットビューワは正確に HTML ドキュメントを判断するわけではなく、指定したファイル内にある applet 要素を探し出し、記述に従って目的のクラスファイルをロードする仕組みになっています。そのため、わざわざ完成された HTML ドキュメントを用意しなくても、アプレットを記述しているソースコード内にコメントとして applet 要素を書いておけばアプレットビューワはそれに反応してくれます。
import java.applet.Applet; //<applet code= "Test.class" width="400" height="400"></applet> public class Test extends Applet { public void init() { System.out.println(getClass() + ".init()"); } public void start() { System.out.println(getClass() + ".start()"); } public void stop() { System.out.println(getClass() + ".stop()"); } public void destroy() { System.out.println(getClass() + ".destoroy()"); } }
コード1は、JDK 付属の appletviewer.exe で実行されることを想定したアプレットです。次のようにアプレットビューワをソースコードを引数に起動してください。ソースコードには applet 要素がコメントとして書かれているため、アプレットビューワはこの applet 要素を参考にアプレットを起動します。
...\Sample>appletviewer Test.java
アプレットビューワが起動しても、このプログラムはグラフィカルな処理を何も行わないため、真っ白なウィンドウが表示されるだけです。
アプレットビューワが起動し、applet 要素が解析されると code 属性に記述されているクラスファイルをアプレットと認識してカレントディレクトリからロードします。このとき、アプレットの init() メソッドが呼び出されます。このプログラムでは System.out.println() メソッドを使って init() メソッドが呼び出されていることを標準出力に出力するため、アプレットビューワをコンソールから起動している場合はコマンドラインにテキストが出力されるでしょう。
同様に、アプレットがスタートすると start() メソッドが呼び出され、アプレットビューワを最小化すると stop() メソッドが呼び出されることを確認することができます。アプレットビューワを終了しようとすれば、先に Test クラスのリソースが解放されるため destory() メソッドが呼び出されてアプレットがメモリから解放されることを知ることができます。
ここまでが、アプレットの初期化と終了処理の流れとなります。コード1では main() メソッドが存在しませんが、main() メソッドを記述しても問題はありません。例えば、アプレットとしてもアプリケーションとしても起動することができるクラスを作ることも可能です。
因みに、コード1で生成した Test.class をブラウザで実行することも可能です。ただし、コンテンツは何も表示しないので、意味のある結果にはならないでしょう。