「アプレットについて」
今まで作ってきたプログラムは、基本的に全て「アプリケーション」でした。すなわち、javaコマンドで実行して動かす、というものですね。しかし、Javaのプログラムにはこの他にも様々な形のものがあります。その代表的なものが「アプレット」です。
アプレットというのは、Webブラウザ内に表示して実行するタイプのプログラムです。Java対応のWebブラウザではアプレットを表示するための専用タグをサポートしており、HTMLのタグを記述するだけで簡単にアプレットを呼び出せます。このアプレットというもののおかげで、Javaは一躍注目されるようになったといってもよいでしょう。Javaが登場した当時、Webというのはテキストと静止画の絵しかない世界でした。そんな中で、「ブラウザの中でプログラムが動く」というのは画期的なことだったのです。
このアプレットというのは、今まで作ったアプリケーションとは違う造りになっています。アプリケーションをそのままHTMLのタグから呼び出しても、アプレットとして動かすことはできません。アプレットとして使うプログラムは、アプレットとしての利用に必要な機能を備えていなければいけません。
Javaにはそのための専用クラスが用意されています。「java.applet.Applet」というのがそれで、このクラスを継承してクラス定義をすれば、それが自動的にアプレットとして認識されるようになります。
では、とりあえず簡単なアプレットを作って動かしてみましょう。
import java.applet.Applet; import java.awt.*; public class MyApplet1 extends Applet implements Runnable { int lastX; String str; Thread t; public void init () { str = "Hello, Applet!"; lastX = 100; t = new Thread(this); t.start(); } public void paint(Graphics g) { g.setFont(new Font("Dialog",0,24)); g.setColor(Color.blue); g.drawString(str,lastX,35); } public void run() { while(true) { lastX = lastX - 10; if (lastX < -150) lastX = 300; repaint(); try { t.sleep(100); } catch(Exception e){} } } }
これがそのソースコードです。これをコンパイルしてMyApplet1.classというプログラムを作ります。そして、以下のようなタグをHTMLの<body>内に埋め込んで、Webブラウザで表示してみましょう。
<applet code="MyApplet1" width=300 height=50>
</applet>
MyApplet1の実行
|
この<applet>というタグは、code、width、heightといったオプションをもっています。他にもありますが、この3つが必須だと考えればよいでしょう。codeで呼び出すクラス名を、widthとheightで表示する横幅と縦幅をそれぞれ指定します。
上に作成したアプレットを表示させてみました。青いテキストが右から左へとスクロールしているのが見えますか? 無事に表示されたら、アプレットは完成ということになります。 ここでは、前回登場したスレッドというのを使って、簡単なアニメーションをさせてみました。
見ればわかりますが、アプレットはアプリケーションと違い、ウィンドウの中にはめ込まれた形で動きます。従って、メニューなども使いませんし、多くは大きさを変更することもありません。そして実行中でも、ウィンドウを閉じてしまえば消えてしまうというはかない存在でもあります。
ソースコードを見ると、いくつかのポイントが見えてきます。アプレットとの違いを念頭に入れて、ソースコードをチェックしてみましょう。
import java.applet.Applet;
まずは、java.applet.Appletをimportして取り込みます。アプレット関係はこのクラス1つですみますから、importは割と簡単ですね。
public class MyApplet1 extends Applet implements Runnable {
クラス定義の部分は、「extends Applet」となります。アプレットは必ずAppletをextendsで継承しなければいけません。ここではスレッドを使う関係で、その後にimplements Runnableがついています。
このjava.applet.Appletというクラスは、java.awt.Panelを継承して作られています。ですから、Panelにコンポーネントをaddする感覚でButtonやTextFieldを組み込んだりできますし、paintメソッドを使って表示をさせることもできます。ここでは、paintを使って簡単な表示をしているわけですね。
public void init () {
その後に、こんなメソッドがあります。これが、実はここでの最大のポイント。このinitというメソッドは、アプレットの初期化メソッドなのです。
ソースコードを見ると、今までのお馴染みのコンストラクタやmainメソッドが見当たりません。それも道理で、アプレットではこれらのメソッドは使いません。――アプレットというのは、アプリケーションのように独立したプログラムではなく、Webブラウザの中で呼び出されて動いているものです。つまり、Webブラウザの中のJava仮想マシンで動いているプログラムの中から必要に応じてアプレットのインスタンスが作られ実行される…というようなイメージで考えるとよいでしょう。ですから、Webブラウザの仮想マシンには、アプレットの初期化や終了時の処理などの処理が最初から用意されており、我々は必要に応じてそれらのメソッドを追加していけばよいようになっているのですね。
こうした「アプレット専用のメソッド」は他にもあります。そしてアプレットとアプリケーションのプログラムの最大の違いは、それらの専用メソッドを使うところにあるのです。では、ここで主な専用メソッドを整理しておきましょう。
public void init () { … }
アプレットがロードされる時、一番最初に1度だけ呼び出される。通常、初期化のための処理はここで行なう。
public void start () { … }
アプレットがアクティブになった際に呼び出される。アプレットをロードする時は、まずinitが呼び出され、その後にこのstartが呼び出される。initと違い、startはアプレットがアクティブになる度に実行される。
public void stop () { … }
アプレットが非アクティブとなったときに呼び出される。アプレットを終了する時などの処理はここで行なうことが多い。これで停止時の処理をし、再びアクティブになったらstartで再開の処理をする、と考えればいい。
public void destory () { … }
アプレットが破棄される時に1度だけ呼び出される。アプレットが破棄される時は、その前にstopが呼ばれ、一番最後にこのdestoryが呼び出される。
とりあえず、この4つを覚えておくとよいでしょう。通常、もっとも多用されるのはinitかstartです。終了時の処理は、しないことも多いからです。アプリケーションと違い、アプレットは、Webブラウザのウィンドウを閉じたりブラウザを終了すれば、否が応にも強制的に終了してしまいます。「終了ができない」なんてことはないですし、後述しますが、現在の状態を保存して…なんてこともまずないわけです。
アプレットの最大の問題は、「アプリケーションに比べて、やれることが極端に少ない」ということです。では、どのようなことができないようになっているのでしょうか。主なものをまとめると以下のようになります。
・アプレットがあるサーバ以外のサーバへのアクセス。
・ローカルボリューム(要するにパソコンのディスク)へのアクセス。
・ファイルの保存。(読み込みは、アプレットがあるサーバ上のものに限りできる)
・(多くの場合)ローカルボリューム上での実行。
一応、Java2ではセキュリティ関係が強化されて、様々な制限事項も緩和する方法はあるのですが、原則として「アプレットでは、その場に読み込んで動かす以外のことはほとんどできない」と 考えるべきでしょう。
最後の「ローカルボリューム上での実行」というのは、「WebブラウザのJava仮想マシンはたいていこれを禁じている」と考えて下さい。JDKに付属するappletViewerというアプレットの実行プログラムでは、ローカルボリュームにあるアプレットも実行できますが、一般のWebブラウザでは、ネットワーク経由でダウンロードしたアプレットしか動かせません。
こうした制限は、ネットワーク上からダウンロードして動かすというアプレットの特徴からして、やむを得ぬ面があります。もし、ローカルボリュームへのアクセスやファイルの書き換え、他のサイトへのアクセスが可能であったとしたら、ローカルマシンのファイルを書き換えたり、重要な情報を秘密のサイトに送ってしまったりといった危険なアプレットも作れることになります。どこの誰が作成したのかもわからないアプレットにそんな物騒な仕掛けが組み込み可能としたら、おっかなくってとてもアクセスなんてできませんよね。なにしろアプレットは、そのページを開いただけで自動的にロード実行されてしまうんですから。
このような理由により、ファイルの書き出しなどは厳重に制限されています。またファイルの読み込みも、ちょっと変わったやり方をしないといけないので注意が必要です。ただし、その分、使い方が簡単なのが嬉しいところです。
以前の第10回で、グラフィックを読み込む方法を説明しましたが、アプレットでグラフィックファイルを読み込み表示するようなものを作ってみましょう。先ほどのMyApplet1をちょっとだけ修正して、テキストの代りに読み込んだテキストを表示するようにしてみます。(表示するイメージは100×50の大きさとしました)
import java.applet.Applet; import java.awt.*; public class MyApplet2 extends Applet implements Runnable { int lastX; Image img; Thread t; public void init () { img = getImage(getDocumentBase(),"ImageL.gif"); lastX = 100; t = new Thread(this); t.start(); } public void paint(Graphics g) { g.drawImage(img,lastX,0,this); } public void run() { while(true) { lastX = lastX - 10; if (lastX < -100) lastX = 300; repaint(); try { t.sleep(100); } catch(Exception e){} } } }
MyApplet2の実行
|
これで、魚のイラストが右から左へと動くアニメーションが表示されればOKです。 ここでは「ImageL.gif」というファイルを読み込み、アプレットに表示させています。
ここでのイメージの読み込みは、initメソッドにある以下のメソッドで行なっています。
img = getImage(getDocumentBase(),"ImageL.gif");
ここでは、getImageというメソッドが使われていますが、これはAppletクラスに用意してある、イメージ読み込み用のメソッドです。パラメータは2つあり、1つ目に読み込むディレクトリを示すURL(これは「URLのString」ではなくて、URLというクラスのオブジェクト)、2つ目にファイル名が来ます。
1つ目の「URL」の指定がちょっとわかりにくいかも知れませんが、これは通常、やはりAppletクラスに用意されている以下のようなメソッドを利用するのが一般的です。
getDocumentBase() ――HTMLの文書がある場所を示すURLを返す。
getCodeBase() ――アプレットのクラスファイルがある場所を示すURLを返す。
これらを使えば、アプレットがある場所のURLは得られますから、これらを使って、getImageでその場所にあるイメージファイルを読み込み、Imageとして扱うことができるというわけです。
Appletクラスには、この他にもサウンドファイルを読み込むメソッドなどもあります。これらを使えば、比較的簡単にファイルを読み込むことができます。とりあえず、それだけでもけっこう面白そうなアプレットは作れるようになりますよ。
ファイルの書き込みなどが必要になったら、それはアプレットではなくアプリケーションとして作成すべきものである、と考えて下さい。アプレットでできることとできないことをよく考えた上で使えば、アプレットはWebを飾るすてきな小道具として役立ってくれますよ。