page12(update:2016/12/20)


[ prev | next | index ]

12. アプレット

目次

目次

12.1 アプレット(Applet)

javaプログラムの主な実行形態にはjavaVMによって直接実行するApplication、Webブラウザ(IE等)などの他のアプリの中で実行されるApplet、そしてTomcat等のアプリケーションサーバ の上で実行されるServeletの3種類がある。ここではAppletについて説明を行う。

ブラウザ上でのApplet実行の許可設定

WebブラウザでのAppletプログラムの実行はセキュリティーの問題で制限されるようになりました。制限はコントロールパネルにあるjavaコントロールパネルの設定にしたがいます。

appletを提供するサーバーが証明書を持っていない場合は、例外サイト・リストへサーバーを追加して利用許可を行うことが必要です。

 

目次

12.2 Appletの主なメソッド

アプレットを実行可能なアプリケーションにはアプレットビューアやAppletを実行するプラグインを組み込んだWebブラウザ(Internet Explorer やFirefox)などが在ります。 これらの実行ではjavaVMをアプリケーションから使う形でプログラムを動かします。従ってjavaVMやクラスライブラリーなどのjava実行環境が用意されていることも必要です。

※ブラウザなどへのプラグインで実行する場合でも、Windowsの場合はjavaコントロールパネルの設定を参照ます。これはセキュリティーの問題を軽減するためと思われます。

アプレットは幾つものオブジェクトが協調して動くプログラムです。このオブジェクト群の中にあるAppletのインスタンスをプログラマーは自分の作ったアプレットに置き換へ、プログラムを実行します。

Appletに対しては、下記の様なメソッドが必要に応じて呼び出されます。そこでアプレットのプログラムを作るときはAppletを継承し、これらのメソッドを上書きすることで目的の動作を行うように作ります

アプレットビューアなどから呼ばれるメソッドの主なものは下記のようになります

※SWING版のアプレットJAppletがありますが、ここでは取り上げません。

1)インスタンスの状態変化

上記のメソッドによるAppletインスタンスの状態変化は下記の図のようになる。

2)メソッド呼び出しのタイミング

Webブラウザの例で説明します。先ずAppletタグの有るページを読込むと、タグに指定されたAppletクラスをWebサーバから読み出し、インスタンスを生成しinit()を呼び出し、続いて実行開始メソッドstart()を呼び出します。これで表示されたページの中でAppletが実行中になります。

※Appletプログラムの読み込みはAppletタグの有るページを提供したサーバーからしか行えません。

ペ−ジ移動が起こるなどしてAppletが表示されなくなったときは実行停止メソッドstop()を呼び Appletを停止し続いてdestroy()を呼んでインスタンスの後始末を行って破棄します。

 

注意:以前のブラウザでは下記の動作をしていました。しかし、現行のブラウザは上記のとおりです。 裏でプログラムが動き続けるとセキュリティー上問題があるからと思われます。

 ペ−ジ移動が起こるなどしてAppletが表示されなくなったときは実行停止メソッドstop()を呼び Appletを一時停止の状態にします。しかし、Appletタグのページがページ履歴に残っている間はAppletのインスタンスは存在し続け 、元のペ−ジへ戻ればWebブラウザは再びstart()を読んでAppletを動かします。 履歴から外れた場合にのみWebブラウザはdestroy()を呼んでインスタンスの後始末を行い続いて破棄します。この間のブラウザとアプレットの状態変化は下図のようにまとめられます。。



初期の動作はこのようになっていました。しかし、現在はAppletのページから移動するとstopとdestroyを実行しAppletプログラムは破棄されるようになっています。

目次

12.3 初めてのアプレットプログラム

IEなどのWebブラウザでアプレットを表示するには以下の2つのファイルが必要です。

1)アプレットのクラスファイル

Appletを継承して作ったプログラムのクラスファイル。下記のソースをコンパイルしてクラスファイルを作ってください。
 

/*TestApplet.java*/
import java.applet.Applet;
import java.awt.*;

//HelloWorldと大きな文字で表示するだけのアプレット
public class TestApplet extends Applet
{
    public void paint(Graphics g)//表示だけ上書き
    {
         g.setColor(Color.blue);
         g.setFont(g.getFont().deriveFont(Font.PLAIN,50.0f));
         g.drawString("Hello World",10,80);
    }
}

2)HTMLファイル

※IEなどのWebブラウザでAppletを実行するためには、セキュリティーを通過する必要があります。

AppletをWebのページ内で動かすには、WebページにAppletを起動するタグを記述する必要があ値ます。

上記のコンパイル済みクラスファイルTestApplet.classと下記のHTMLファイルTestApplet.htmlをWebサーバーのフォルダに置いてください。この後、ブラウザからTestApplet.htmlファイルのURLを見てみましょう。

※学科の環境ではZドライブのWWWフォルダにファイルを置けば、学科内用のWebサーバーを通して学科内で見ることができます。

※学科内用のWebサーバーを使う場合のURLはwww.ed.ibe.kagoshima-u.ac.jp/~あなたのID/TestApplet.html

<HTML><HEAD><TITLE>TestApplet.html</TITLE></HEAD>
<BODY>
<H1>TestAppletの実行ページ</H1>

<applet code="TestApplet.class" codebase="./" width="300" height="120">
 ここがAppletタグ
</applet>
ソースコード:<A HREF="TestApplet.java">TestApplet.java</A>
</BODY>
</HTML>

ここで<applet>から</applet>までがアプレットタグと呼ばれる部分です。
タグのプロパティーの意味は各々

セキュリティーで止められる場合

幾つか原因が考えられます

1)javaを提供するサーバーが証明書を持っていない。
このページの初めの方に書いたような設定で回避できますが自己責任。 

2)PCにインストールされたjavaのバージョンが古い
最新のバージョンにアップデートする以外に在りません。

3)Appletのみを実行できればいいのならappletviewerが使えます。

ブラウザでの実行が拒否される場合でも、javaの開発環境の中に用意されたappletviewerでなら実行する ことができる。ただしセキュリティーのチェックが無いので自作のAppletの実行に限定して使ってください

コマンドプロンプト>appletviewer  HTMLファイルのURL

「HTMLファイルのURL」は 例えば、

ローカルに在る場合はファイル名

コマンドプロンプト>appletviewer  TestApplet.html

ネット経由の場合は 通常のURL

コマンドプロンプト>appletviewer http://www.ics.kagoshima-u.ac.jp/edu/gengo2j/p11.html

目次

12.4 動くアプレットプログラム

上のプログラムは動かないので面白くありません。説明したメソッドも全く上書きしませんでした。そこで以前に説明したThreadを用いて動くAppletをつくってみます。この場合はstartやstopを上書き し、別スレッドで実行する処理をrunメソッドとして記述します。

0)インターフェイスのRunnableを実装し、Appletを継承したアプレットクラスを定義します。ここの例ではそれをTestApplet2としましたが、名前は自由です。 メソッドの中身を書いていませんが、後述する内容に書き換えてください

public class TestApplet2 extends java.applet.Applet implements Runnable
{
	
	Thread thread=null;/*別スレッドを動かすためのインスタンスを参照する変数*/
	
	public void init(){/*初期化*/}
	
	public void destroy(){/*後始末*/}

	public void start(){/*開始  中身は以下に記述*/}
	
	public void stop(){/*停止  中身は以下に記述*/}
	
	public void run(){/*別スレッドが実行  中身は以下に記述*/}
	
}

1)Runnableの実装でrun()メソッドが必要になります。ここではrunの中で変数threadがnull以外の場合に無限ループしながら 繰り返したい処理を行います。また、このスレッドが時間を使いすぎないように休みを入れています。

public void run()
{
	while(thread!=null){
			/*ここに別スレッドで繰り返したい処理を書く*/
			
		try{	/*別スレッドが時間を使いすぎないように休みを入れる処理*/
			Thread.sleep(100);//0.1秒休む
		}catch(Exception e){/*例外でも何もしない*/}
	}
}
	
	

2)アプレットのstart()が呼ばれたら、Threadのインスタンスthreadをつくり、thread.start()メソッドを呼んで別スレッドを開始します。この別スレッドがrun()を実行してくれます。

public void start()
{
	if(thread==null){/*startを重複して呼び出しても何もしないように*/
		thread=new Thread(this);
		thread.start();
	}	
}

3)アプレットのstop()が呼ばれたら、threadのストップを呼ばずにthreadにnullを代入するだけです。これでrunに書かれたループは終了しrunの実行が終わって別スレッドは停止します。

public void stop()
{
	thread=null;
}

注意:thread.stop()は呼ばないでください。thread.stop()はスレッドを強制終了するので、たとえ重要な処理の途中でもスレッドは終了してしまいます。

図にすると次のようになります。図のオブジェクトで下線付きはインスタンス、下線の無いThreadはクラスです。

赤い字でloopと書いた枠が繰り返し実行される部分で、繰り返す条件はthread != nullです。

例として動く波紋を表示するアプレットを作りました。描画部分などプログラムが長くなるので、別ページとします。下記のリンクから見てください。
動くアプレットのページTestApplet2.html

目次

12.5 課題10(初期ファイル)

時刻を表示するアプレットを作ってください。Appletを継承したクラスの名前はP10です。.レポートツールの初期ファイルはP10.java です。アプレットを表示するhtmlファイルはこちらで用意したP10.htmlを使ってください。


 ここがAppletタグ
アプレットプログラムのレポートツールでの作成方法はreportのページを参照。前の12.4と以下の説明を見て挑戦してください。

ファイルの配置

レポートツールJReport.jarとP10.java、P10.htmlをZドライブ内の同じフォルダに置いてください。この状態で、このレポートツールを起動してP10.javaとP10.htmlをツールに設定して課題作成とレポート送信を行うこと。

※ディスクトップ内のフォルダに置くと、演習室の環境ではツールがファイルを正しく見つけることができません。 

継承や実装の方法を思い出すこと

クラスP10はjava.applet.Appletを継承し、Runnableを実装して作る。

Threadを使った並列処理で表示する時刻を書き換えるのでThreadの使い方を思い出す。

暦法の違い

時刻の値は国によって違います。ここで日本時間としてしまうと、他の国では変な時計になってしまいます。このような国や地域を区別するインスタンスがjava.util.Localeです。

まずAppletを実行する環境の既定のLocaleを取得し、これを元にその地域の歴(java.util.Calendar)のインスタンスを準備します。これをオブジェクトのフィールドに保持しましょう。

さらに時刻はSystem.currentTimeMillis( )でミリ秒単位の値が返されるので、これを使うことにします。ここで前回の表示時刻を秒単位の値でフィールド t0 で 持つことにします。これは次の表示の書き換え等で無駄な描画を避けるためです。

Calendar carendar=Calendar.getInstance(Locale.getDefault()); 

long t0=-1;//t0は過去に描画した時の秒針の値を覚えておくためのフィールド

.......

画面を無駄に更新しない

run( )で繰り返し画面の再描画(Appletのrepaint( ))メソッドを呼ぶことで時計の値を書きなおしますが無駄に書き直すのは良くないので、秒針の値が変わった時だけ書き直すことにします。

public void run()
{
	while(thread!=null){
		long t=System.currentTimeMillis()/1000;//ミリ秒単位なので千で割って秒単位に

		if(t!=t0)
		{//秒が変わったときだけ再描画
			t0=t;
			repaint();
		}	
		try{
			Thread.sleep(100);//0.1秒休む
		}catch(Exception e){/*例外でも何もしない*/}
	}
}

時刻の文字列を表示

描画メソッドで時刻の文字列を描画するのですが、ここでまずは文字列を作らなければなりません。ここで暦法に従って時分秒の値を求め、この値から時刻表示のフォーマットに合わせた文字列を作り、そして...

public void paint(Graphics g)//表示だけ上書き
{

	carendar.setTimeInMillis(System.currentTimeMillis());//現在時刻をセット

	int h=carendar.get(Calendar.HOUR_OF_DAY);//24時間制の時間を取得
	int m=carendar.get(Calendar.MINUTE);//分を取得
	int s=carendar.get(Calendar.SECOND);//秒を取得

	//C言語のprinntfみたいな書式付き文字列生成が可能になっています
        String text=String.format("%02d:%02d:%02d\r\n",h,m,s);

	......表示する文字の大きさを設定し、.....
	......  Appletに描画する   .....
}

※文字フォントの大きさの変え方は、このページのTeswtApplet.javaあるいは「9.継承と実装」の例題9bを参照.

目次


[ prev | next | index ]