==========================================================================================================

		Learn more about Java Programming :                    I-ichirow Suzuki

===========================================================================================================

	1 Javaとは何か
		Java の歴史
		Java の特徴
		Java の動作環境

	2 Java言語の基本
		アプリケーションとアプレットの違い
		アプレットプログラムの構造
		プログラムの作成・実行
		Hello World!
		フォントの変更
		フォントカラーの変更
		C 言語との比較
		変数の使用
		変数を用いた計算
		インクリメント
		変数のデクリメントとForループ
		条件分岐 IF  文字列演算 文字列の結合は + でできる。

	3 メソッド
		メソッドの使用
		メソッド
		ifを用いたメソッドの使用例
		メソッドの値を返す
		メソッドの引数を使用して値を渡す
		Javaにはポインタが無い!!
		オーバーロード
		メソッドのオーバーロード
		いくつかの特殊なメソッド
		 ついでにHTML にアプレットを入れるために必要な属性
		アプレットの引数

	4 クラスとインスタンス
		オブジェクト指向プログラミング
		クラスの定義
		学生クラスの定義
		学生クラスに画面表示用の関数を作成
		インスタンスを作る
		オブジェクトに値を渡す
		コンストラクタ
		this キーワードを使う
		継承
		オーバーライド

	5 グラフィックスとオーディオ
		Graphics クラス
		Font クラス Color クラス
		Image クラス
		play メソッドと AudioClip クラス

	6 アニメーション
		repaint メソッド
		ちらつきの防止

	7 イベント
		イベントとは
		マウスイベント
		マウスモーションイベント
		キーイベント
		Adapter クラス

	8 ユーザインターフェース
		基本的な部品
		レイアウト
		チェックボックス

	9 マルチスレッド
		プロセスとスレッド
		排他制御
		待ち合わせ


///////////////////////////////////////////////////////////////////////////////////////////////////////////
1 Java とは何か

◆Java の歴史
1991年6月: Sun Microsystems が Oak インタープリタ(Java の前身)の開発に着手。当初の目的は消費者向け電子機器
の制御用。
1994年9月: WebRunner (HotJava の前身)が開発される。
1995年5月: SunWorld EXPO で発表される。
1996年1月: JDK 1.0版がリリースされる。
言語としてはきわめて新しい。(cf. Fortran 1957年、LISP 1962年、BASIC 1965年、Pascal 1971年、Prolog 1971年、C
 1972年、Smalltalk 1972年、C++ 1982年)

◆Java の特徴
バイトコードインタプリタである。--- Java virtual machine のあるところならば、どこでも実行できる。ただし、
最近では Just-in-time Compiler により、機械語に変換しながら実行する方式が普及しつつある。
オブジェクト指向言語である。--- プログラムの開発、再利用が容易。 (ホントか?)
言語仕様が (C++ に比べて) シンプルである。
セキュリティ機能を持っている。--- ダウンロードしたプログラムを安心して使える。
マルチスレッド対応である。--- インタラクティブな処理がしやすい。ただし、ハードウェアや OS の機能に制限され
る。
まったく新しい機能を実現したわけではないが、WWW で必要とされる機能をバランス良く取り込んでいる。

	会社で使う会計プログラムなどではCOBOL
	科学技術分野の計算処理ではFORTRAN
	オペレーティングシステムなどのシステムプログラムを作成する場合にはC/C++
	ネットワーク環境に最適な言語はJava

Javaはスタンドアロンプログラムを作成する事も出来るし、WWWブラウザ向けのアプレットを作成する事も出来る
スタンドアロンのJavaプログラムはWWWブラウザ内部では実行できない。
JavaアプレットはMicrosoftInternetExplorerやNetScapeなどのWWWブラウザの内部で実行される
Javaアプレットは特定のデバイスに依存しない。このためWindows/Macintosh/UNIX上でも実行する事が出来る
最終的に生成されるプログラムコードは特定のCPUに依存する。JavaはブラウザのJavaVirtualMachineによってユーザー
プラットフォームのCPUが理解できるバイナリコードに変換される。
アプレットやスタンドアロンプログラムとしてJavaプログラムを作成する為にはJavaコンパイラと呼ばれる特別なプロ
グラムが必要である。


◆Java の動作環境
Java で書かれたプログラムは Java virtual machine (JVM) のあるところならば、どこでも動かすことが出来る。逆
に言うと、JVM がなければ、いくらマルチプラットフォームなJava でも動かすことは出来ない。JVM は Netscape な
どのブラウザにも内蔵されているし、単独のアプリケーションとしても利用できる。
Java のプログラムを作るためには、Java Development Kit (JDK) or Microsoft VisualJ++ が必要である。

◆アプリケーションとアプレットの違い
アプレットは HTML 文書の中から呼び出し、Web ブラウザが実行する Java プログラムである。Netscape などは、HTML
 の中にアプレットが含まれていると自動的に実行するので、ネットサーフィンしていると、どこの馬の骨とも分から
 ないアプレットをついうっかり実行してしまうことがある。そこで、そのアプレットが悪いことができないように機
 能を制限してある。

ファイルアクセスは制限される。
ネットワーク経由で接続できるホストは、そのアプレットがあったホストだけ。
他のプログラムを実行したり、ライブラリをロードしたりすることはで きない。

◆アプレットプログラムの構造
実行が開始されるクラスは、java.applet.Applet クラスのサブクラスでなくてはいけない。ファイルの最初の方に imp
ort java.applet.Applet と書いて、アプレットクラスを使うことを指定する。そして、クラス定義のクラス名の後ろに
 extends Applet と書くと java.applet.Applet クラスの持っている機能がこのクラスでも使えるようになる。サブク
 ラスについて詳しくは次回以後に説明。


// ------------------------------------------------------------------------------------------
// まとめ

コンパイラ
	コンパイラとはプログラミング言語で書かれたプログラムをコンピュータが解る機械語に翻訳し、実行出来る
	形にするプログラムの事

インタプリタ
	プログラミング言語で書かれたプログラムをコンピュータに解る機械語に通訳し、実行して行くプログラムの
	事を言います。

中間言語
	Javaはコンパイラ言語ですがJava仮想マシン(Java virtural machine)と言われる架空のCPUの機械語に翻訳
	し、それをインタプリタで実行します。

遅い
	Javaインタプリタは中間言語をいちいち解釈して実行する為、実行速度が遅くなります。C/C++プログラムよ
	りも20倍あるいは100倍以上も遅い訳です。


アプリケーション
	C/C++/アセンブリ言語等が作るOS上のコマンドとして実行出来る通常のプログラムに相当する物で、単体で動
	かす事を目的にしているプログラムです。
	Javaの場合は単体と言ってもJavaランタイム(Javaインタプリタ、JITコンパイラ)が必要です。

アプレット
	アプレットは他のプログラムに埋め込んで使う小さなプログラムの事を言います。
	HTMLに埋め込んで使う場合が多いです

MicrosoftVisualJ++は本来マルチプラットフォームを期待する事が出来るJavaではありません。あくまでWindowsOSの
上で動作するJavaを基本としています。マルチプラットフォームアプリケーション、又はアプレットを勉強したければJ
DKを使用する事をお勧めします。


	1. www.sun.co.jp/java.jp/
		で JDKをダウンロードしてインストール
	2. Autoexec.batに
		Path c:\windows;c:\windows\command;c:\JDK\BIN
		と追加記述してPATHを通してください
	3. デスクトップ等にフォルダを作成してその中に新規作成にて新規ファイルを作成。
		フォルダ名 : Java(自分の好きなフォルダ名でよいです)
		ファイル名 :  hoe.java(拡張子がjavaであれば何でもよいです)


	hoe.javaをテキストエディタで開いて以下のソースを記述して下さい

		// hoe.java ---------------------------------------
		class hoe
		{
			public static void main(String args[])
			{
				System.out.println("Hello Java") ;
			} // End main() ;
		} // End class

		// End hoe.java ------------------------------------

	4. フォルダを開いた状態でスタートボタンから「ファイル名を指定して実行」を選択して
		command を入力して実行
	5. コマンドプロンプトが c:\windows\デスクトップ\Java>	になっている事を確認して
		javac hoe.java (javac ソースファイル名) と入力してEnterキー <<コンパイルされます
	6. エラーを修正 (デバッグ)
	7. エラーがなくなったら コマンドプロンプトに java hoe と入力します。(java ファイル名) です

	補足・・・
	アプレットを作成する場合はHTMLファイルにAppletタグを挿入する必要があります。後ほど説明します

// -----------------------------------------------------------------------------------
作者より一言・・・

	1.Javaはオブジェクト指向言語ですが条件判断すら出来ない「史上最低の言語HTML」を保管するためにオブ
	ジェクト指向がいるかと言えば明らかに必要ありません。

	2.インターネット用言語はBASIC程度の能力の言語(JavaScript, VBScript)で十分です
	しかし、Javaでないと出来ない事もあるのも事実です。

	3.アプリケーションソフトウェア開発と言う事ならば、はっきり言ってJavaは役立たずです。少なくとも即
	戦力にはなりません。今の所ホームページ以外に使うには問題がありすぎます。

	4.通常大きなプログラムを作成してもあまり気になりませんがネットワークを使用する事を目的としているJ
	avaによって大きなプログラムを作成すれば読み込む度にその大きなプログラムファイルをダウンロードする
	事になります。大きなプログラムは現実的ではありません。ファイルサイズは画像レベル同等で考えて下さい

	5.今後のJava ?
		JavaがOSに変わる物になる
		C/C++に変わってプログラミング言語の王者となる
		ホームページを強化する為に盛んに使われる
		小さなアプレットを作る為に細々と生き残る
		使われなくなる

		最終 1996年のJava騒動はプログラミング言語市場における最も愚かしい馬鹿騒ぎと評価されるに違
		いありません。たかだか家電用言語を転用した言語ですから・・
		シェアの小さなOSの生き残りを賭けた短期決戦の捨てゴマでしかありません。

///////////////////////////////////////////////////////////////////////////////////////////////////////////
2 Java 言語の基本


◆プログラムの作成・実行

----------------------------------------------------------------------------------------
◆Hello World!

import java.awt.* ;				// C/C++のincludeとおなじ
import java.applet.* ;

public class Applet1 extends Applet {	// publicはブラウザがこのクラスにアクセス出来る様にする為の
						// アクセス権限の指定
						// Javaはヘッダーファイルが無い為Classから始まる
						// Appletを作成するのでAppletと記述
						// Appletクラスから派生したという意味でextendsを記述
						// public クラス名 extends Applet
						// Javaはブレス{}でコードをグループ化します。
	public void paint(Graphics g) {		// paint()関数のGraphicsクラスを使用 変数を g とする
						// Javaでは関数をメソッドといいます。
		g.drawString("HelloWorld", 5, 25) ;
						// drawStringはC/C++のprintf/coutと同じ
						// 表示したい文字列を""で囲みます。
						// 2つ目3つ目の引数は文字を表示させる為の座標軸を表します。
	}
} 						// End class


上記通り間違いなくタイプして下さい。たまに僕の記述が間違っている事もあります(笑)
行の終わりにはセミコロンが必要です。
出来たらビルドしてコンパイルしてください。クラスファイルが生成されます。

----------------------------------------------------------------------------------------
◆フォントの変更


import java.awt.* ;				// C/C++のincludeとおなじ
import java.applet.* ;

public class Applet1 extends Applet {	// publicはブラウザがこのクラスにアクセス出来る様にする為の
						// アクセス権限の指定
						// Javaはヘッダーファイルが無い為Classから始まる
						// Appletを作成するのでAppletと記述
						// Appletクラスから派生したという意味でextendsを記述
						// public クラス名 extends Applet
						// Javaはブレス{}でコードをグループ化します。
	public void paint(Graphics g) {		// paint()関数のGraphicsクラスを使用 変数を g とする
						// Javaでは関数をメソッドといいます。
		Font font = new Font("Serif", Font.BOLD, 24) ;
						// Fontクラスからfontオブジェクトをnew演算子を使って作成し
						// ます。フォント名を「セリフ,ボールド、24ポイント」に指定
		g.setFont(font) ;		// 変数gにフォントをセットします。
		g.drawString("HelloWorld", 5, 25) ;
						// drawStringはC/C++のprintf/coutと同じ
						// 表示したい文字列を""で囲みます。
						// 2つ目3つ目の引数は文字を表示させる為の座標軸を表します。
	}
} 						// End class


--------------------------------------------------------------------------------
◆フォントカラーの変更

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

public class Applet1 extends Applet {

        Font font = new Font("Times Roman", Font.BOLD, 36);	// fontオブジェクトを作成しフォントを指定

        public void paint(Graphics g) {				// Graphicsクラスからg変数を作成
                g.setFont(font);				// g変数にフォントをセット
                g.setColor(Color.red);				// さらにフォントカラーを追加
                g.drawString("こんにちは", 5, 50);		// 表示
        }
}

--------------------------------------------------------------------------------


◆C 言語との比較
コメント
/* ... */ に加えて、// ... も使える。


名前
英字、数字、_(アンダースコア)に加えて、$(ドル記号)、漢字などのユニコード文字も使える。


プリプロセッサ
Java にはプリプロセッサは無い。#include に相当するのは import 文。


変数の型
- 基本データ型 (boolean, byte, short, int, long, char, float, double)
- クラス型、インタフェース型
- 配列型


ポインタ型は Java には無い。クラス型がそれに対応する。

整数型は次のように対応する。


                        大きさ		C		Java
	                ------------------------------------
			8bit		char            byte
                	16bit		short  		short, char
                	32bit		long            int
                	64bit				long
			------------------------------------

                 (注1) C の int はマシンによって 16bit または 32bit。
                 (注2)Java の整数は char を除いて符号付き。

C では真偽値は整数を使って表していた( 0 が偽で、それ以外が真)が、Java では真偽値型は整数型とは異なる。

プログラムの構成
C では関数定義の集合であったが、Java ではクラス定義の集合。クラス定義の中に変数宣言 とメソッド定義がある。


                class クラス名 {
                        変数の型 変数名, ...
                        返り値の型 メソッド名 (引数の型 引数名, ... ) {
                                文 ...
                        }
                        ...
                }

pulbic はどこからでも呼び出せるという意味。 static は次回以後に説明。

C のプログラムを Java に書き換える最も安直な方法は、一つのクラスを作り、C の関数をすべて public static 付
きのメソッドとして定義し、それから細かい部分を直すやり方である。


制御構造
ループにラベルを付けて、break や continue でどのループから脱出したり、次の繰り返しに行ったりするかを指定で
きる。


局所変数宣言
ブロック(メソッド定義や for 文などのひとまとまりになっている部分)の中だけで有効な変数。C では先頭でまとめ
て宣言。Java では最初に使う場所で宣言すればよい。


仮引数
メソッド呼び出しの時に、値を受け取るための変数。メソッド名の後ろの括弧の中に型と変数名を組にして書く。


--------------------------------------------------------------------------------
◆変数の使用

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet { 			// アプレット用のサンプル

	int age = 30 ;
	String name = "Suzuki" ;
	int Salary = "10000" ;

	public void paint(Graphics g) {
		g.drawString ("Age : " + age, 5, 15) ;
		g.drawString ("Name : " + name, 5, 25) ;
		g.drawString ("Salary : " + salary, 5, 35) ;
	}
} // End class


--------------------------------------------------------------------------------
◆変数を用いた計算

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet { 			// アプレット用のサンプル

	int salary = 10000 ;

	public void paint(Graphics g) {

	salary = salary - 5000 ;			// 悲しい減給の算術計算

		g.drawString ("Next Salary : " + salary, 5, 15) ;

	}
} // End class


--------------------------------------------------------------------------------
◆インクリメント

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet { 			// アプレット用のサンプル

	int age = 30 ;

	public void paint(Graphics g) {

	age++ ;						// 悲しい年齢のインクリメント

		g.drawString ("Age : " + age, 5, 15) ;

	}
} // End class



--------------------------------------------------------------------------------
◆変数のデクリメントとForループ

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

                for (int i = 10; i > 1; i--) {	// forの中で変数を宣言 トリッキー!

	g.drawString("Line Number : " + i, 5, i * 10) ;

                }

        }

} // End class


--------------------------------------------------------------------------------
◆条件分岐 IF  文字列演算 文字列の結合は + でできる。


import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	int TestScore = 85 ;

	public void paint(Graphics g) {

		if( TestScore > 80 ) {
			g.drawString("Your resault : " + TestScore + " OK", 5, 15) ;
		} else {
			g.drawString("Your resault : " + TestScore + " No One more Challange!", 5, 15) ;
		}
	}
} // End class


--------------------------------------------------------------------------------

###############         説明省略事項        ###############################

C/C++のBOOL型は Javaでは boolean です。
Not演算子 ! の使い方はC/C++と同じです。
&& 演算子 || 演算子 も C/C++と同じです。
if for switch while break continue もみ〜んな同じなので省略します(笑)
それなに? という方はC/C++のテキストに戻りましょう〜



例外処理
C では配列の範囲を越えてデータを書き込むと、他のデータが壊れてしまったり、エラーを出して止まったりするが、J
ava ではそのような例外的な事態を検知して、例外処理のためのルーチンを実行する仕組みが備わっている。

例外が起きる可能性がある場合は、try ... catch によって例外処理を定義するか、throws によってそのメソッドを
呼び出したプログラムへ例外を通知しなければならない。

         try {
                 String line = d.readLine();
                 System.out.println("My name is " + line);
         } catch (IOException x) {
                 // 例外処理
         }



///////////////////////////////////////////////////////////////////////////////////////////////////////////
3 メソッド


◆メソッドの使用

メソッドとは・・・・関数です。
関数とは・・・自分で分岐させたりループさせたりして作成したオリジナル自動実行マクロのようなものです。
BASICではサブルーチンなどです。いろいろと用意しておいて必要に応じて呼び出すことによってさまざまな動作をさ
せる事が出来ます。当然もともと用意(定義)されている関数もあります。必要が無ければ当然書く必要はありません。


--------------------------------------------------------------------------------
◆メソッド

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	public void hoe1( Graphics g ) {		// hoe1関数を用意
		g.drawString("hoe1", 5, 15) ;		// 呼び出されるとhoe1を表示
	}

	public void hoe2( Graphics g ) {		// hoe1関数を用意
		g.drawString("hoe2", 5, 25) ;		// 呼び出されるとhoe2を表示
	}

	public void paint( Graphics g ) {
		hoe1(g) ;				// それぞれの関数を呼び出す
		hoe2(g) ;
	}

} // End class

--------------------------------------------------------------------------------
◆ifを用いたメソッドの使用例

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	int TestScore = 60 ;						// 単純に君の点数は60点としよう

	public void Ok( Graphics g ) {					// hoe1関数を用意
		g.drawString("良かった合格だ!", 5, 15) ;		// 呼び出されるとhoe1を表示
	}

	public void No( Graphics g ) {					// hoe1関数を用意
		g.drawString("うひゃ〜だめだった・・", 5, 25) ;		// 呼び出されるとhoe2を表示
	}

	public void paint( Graphics g ) {

		if ( TestScore >= 80 ) {
			Ok(g) ;						// それぞれの関数を呼び出す
		} else {
			No(g) ;
		}
	}

} // End class

--------------------------------------------------------------------------------
◆メソッドの値を返す

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	public void paint ( Graphics g ) {

		g.drawString("5 + 5 = " + AddValue(5, 5), 5, 15) ;	//AddValueの引数5,5が下のAddValue()
		g.drawString("5 + 15 = " + AddValue(5, 15), 5, 25) ;	//に渡されます。
		g.drawString("5 + 25 = " + AddValue(5, 25), 5, 35) ;

	}

	public int AddValue ( int x, int y ) { 				// 型がintになっている事に注目
									// int型で値を返す事を意味
		return ( x + y ) ;					// 渡された値を処理してreturnで関数
	}								// 終了後値を返します。

} // End class



--------------------------------------------------------------------------------
◆メソッドの引数を使用して値を渡す

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	public void paint ( Graphics g ) {

		ShowNumber(g, 100, 15) ;				// Paintメソッドのそれぞれの引数に
		ShowNumber(g, 9, 30) ;					// 値を渡しています。
		ShowNumber(g, 4431, 45) ;				// 時間をかけて理解してください。

	}

	public void ShowNumber ( Graphics g, int value, int y) {

		g.drawString("The number is : " + value , 5, y) ;

	}

} // End class

--------------------------------------------------------------------------------

◆Javaにはポインタが無い!!

Javaのメソッドではクラスオブジェクトや配列による変数についてはその値を呼び出されたメソッド側で変更する事が
可能です。あなたがC/C++言語に精通しているならメソッドの内部で呼出もとの変数の内容を変更する為に、ポインタを
使った事があるでしょう。Javaのクラスオブジェクトや配列変数に対するこの機能は働きとしてはC++言語のポインタを
使った場合と良く似ています。ただし、Javaプログラミング言語では、ポインタはサポートされていません。通常の型で
宣言された変数についてはメソッド側で呼び出しもとの変数を内容を変更する事は出来ません。




◆オーバーロード
同じメソッド名でも、引数の数と型が違っていると、違うメソッドとして扱われる。コンストラクタも同じ。


--------------------------------------------------------------------------------
◆メソッドのオーバーロード

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	int AddValues(int a, int b) {

		return (a + b) ;
	}

	int AddValues (int a, int b, int c ) {

		return (a + b + c) ;
	}

	public void paint(Graphics g) {

		g.drawString("1 + 2 = " + AddValues(1, 2), 5, 15) ;
		g.drawString("1 + 2 + 3 = " + AddValues (1, 2, 3), 5, 30) ;

	}

} // End class
--------------------------------------------------------------------------------

◆いくつかの特殊なメソッド

init 	--- アプレットがブラウザに読み込まれたときに呼 び出される。

	public void init() {

		// アプレットが起動した直後に呼び出されます。
		// 通常変数(フィールド)などの初期化を行います。
	}

start 	--- ブラウザがアプレットを含むページを表示する ときに呼び出される。
stop 	--- ブラウザが別のページを表示するときに呼び出 される。アニメーションなどを行なうときは、ここで実
	行を停めるように設 定しておかないと、CPU やメモリを浪費し続ける。

	Thread someThread = null ;

	public void start() {

		inf (someThread == null) {

			someThread = new Thread (this) ;
			someThread.start() ;
		}
	}

	public void stop() {

		if (someThread != null) {
			someThread.stop() ;
			someThread = null ;
		}
	}

destroy	--- ブラウザが終了するときに呼び出される。
	アプレットが画面に何か表示するのも、ブラウザから呼び出されたとき。

	public void destroy() {

		if (someThread != null) {

		//メモリ上に残っている変数(フィールド)などを開放します

		}
	}


paint --- ブラウザのウィンドウが何かに隠されてから 再び現れたとき、移動したとき、スクロールしたときなどに
	呼び出される。 ただし、window system の設定によっては呼び出されないときもある。

	public void paint(Graphics g) {

		g.drawString("1 + 2 = " + AddValues(1, 2), 5, 15) ;
		g.drawString("1 + 2 + 3 = " + AddValues (1, 2, 3), 5, 30) ;

	}

paint メソッドの引数として Graphics クラスのインスタンスが渡される。これはブラウザが作るので、詳しいことは
(とりあえず) 気にしなくてよい。上の例では Graphics 型の変数 g にこのインスタンスが入る。これは、グラフィッ
クスに関する設定と、文字や絵を描くためのメソッドを持っている。このメソッドを呼び出すためには、g.メソッド名
とする。



◆ ついでにHTML にアプレットを入れるために必要な属性
HTML 文書にアプレットを入れるには、<applet> タグを使う。少なくとも次の3つの属性を指定する必要がある。

code 	--- アプレットプログラムのクラスファイル名。
width 	--- アプレットを表示する領域の幅。
height 	--- アプレットを表示する領域の高さ。
align 	--- アプレットの位置 (教科書168ページ参照)。
hspace 	--- 横方向の余白。
vspace 	--- 縦方向の余白。
codebase --- クラスファイル名の置いてあるディレクト リ。任意の URL が指定できる。

◆アプレットの引数
アプレットに対して情報を渡すには、<applet> と </applet> の間に <param> タグを書く。次の2つの属性がある。

name 	--- 引数の名前。
value 	--- 引数の値。
アプレットプログラムでは、メソッドの引数として受け取れるわけではない。 Applet クラスの getParameter メソッ
ドを呼び出すことによって必要な値を得る。

	<HTML><HEAD><TITLE>hoe Applet</TITLE></HEAD><BODY>
	<APPLET CODE="NoChanges.class" WIDTH=300 HEIGHT=200></APPLET>
	</BODY></HTML>




//////////////////////////////////////////////////////////////////////////////////////////////////////////
4 クラスとインスタンス

◆オブジェクト指向プログラミング
「オブジェクト指向」の厳密な定義はよくわからない。オブジェクトとメッセージ によって現実世界をモデル化しよ
うという考え方全般を指している。

オブジェクトは内部状態を持つ。それに対する外部からの参照/変更は 制限されたやり方で行なわれる。
オブジェクトは他のオブジェクトに対してメッセージを送って、仕事を 頼むことができる。
オブジェクトが受け取ることのできるメッセージの種類と、それに対応 する仕事は決まっている。
オブジェクトは動的に生成/消滅する。

ソフトウェア工学の立場から見ると、オブジェクトは問題を分割し、情報隠蔽を行なうことによってプログラムの保守
性を向上させるもので、抽象データ型から発展した。オブジェクトによる設計の良し悪しは、メッセージ(オブジェク
ト間のインターフェース)の簡潔さ、理解しやすさで判断できる。問題領域ごとにクラスライブラリが蓄積されていく
ことによって、プログラムの開発効率向上も期待できる。
オブジェクト指向言語とは、上のような特徴を持つオブジェクトを言語仕様の中に取り入れているものを指す。Smallta
lk のようにほぼ純粋にオブジェクトだけで出来ているものもあるが、多くは既存の言語にオブジェクトをくっつけた
ものである。(e.g. C + object = objective C / C++ / Java, Common Lisp + object = CLOS)

オブジェクト指向プログラミングとは、オブジェクト指向の考え方(仕事は分担せよ!、自分のことは自分でする!、公
開しなくてもよい情報は隠せ!)に基づいてプログラムを作ることである。オブジェクト指向言語を使わなくても可能で
あるが、使った方が便利である。


◆クラスの定義
オブジェクトの設計図をクラスといい、それによって作られたオブジェクトをそのクラスのインスタンスという。クラ
ス定義には、内部状態を表すための変数と、メッセージに対する応答を定めたメソッドを書く。逆に言えば、同じ種類
の内部変数(値は違うかもしれない)を持ち、同じ種類のメッセージに応答する(個々の応答は内部変数の値によって違
うかもしれない) オブジェクトの集合がクラスである。


--------------------------------------------------------------------------------

◆学生クラスの定義

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Student { 				// Studentクラスの宣言

	}

	public void paint ( Graphics g ) {
							// とりあえず何もしない
	}

} // End class

--------------------------------------------------------------------------------

◆学生クラスに変数を宣言

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Student {					// Studentクラスの宣言

		int ID ;				// フィールド(変数)の宣言
		String Name ;

	}

	public void paint ( Graphics g ) {
							// とりあえず何もしない
	}
} // End class


--------------------------------------------------------------------------------

◆学生クラスに画面表示用の関数を作成

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Student {							// Studentクラスの宣言

		int ID        ;						// フィールド(変数)の宣言
		String Name ;

		public void ShowStudent ( Graphics g, int x, int y) {	// 画面表示用のメソッドを作成
			g.drawString("ID : " + ID,x, y) ;
			g.drawString("Name : " + Name, x, y) ;
		}

	} // End class Student

	public void paint(Graphics g) {

	}

} // End class

--------------------------------------------------------------------------------
◆インスタンスを作る

上の学生クラスは何も個性がなく、のっぺらぼうであるが、インスタンスを作ることはできる。インスタンスを作るに
は new クラス名 () とする。
学生クラスのインスタンスを作る

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Student {							// Studentクラスの宣言

		int ID        ;						// フィールド(変数)の宣言
		String Name ;

		public void ShowStudent ( Graphics g, int x, int y) {	// 画面表示用のメソッドを作成
			g.drawString("ID : " + ID,x, y) ;
			g.drawString("Name : " + Name, x, y) ;
		}

	} // End class Student

	public void paint(Graphics g, int ID, String Name, int x, int y) {

		Student Suzuki = new Student() ;		// StudentクラスにSuzukiオブジェクトを追加
		Student Tomo = new Student() ;			// StudentクラスにTomoオブジェクトを追加

		Suzuki.ID = 1 ;					// それぞれのオブジェクトに値を渡す
		Suzuki.Name = "Suzuki" ;
		Tomo.ID = 2 ;
		Tomo.Name = "Tomo" ;

		Suzuki.ShowStudent(g, 5, 15) ;			// 2つ目、3つ目の引数はShowStudentのなかの
		Tomo.ShowStudent(g, 5, 25) ;			// xとyです
	}
} // End class

--------------------------------------------------------------------------------
◆SuzukiオブジェクトとTomoオブジェクトに値を渡す

オブジェクトを使ってクラスの変数に値を渡す場合はドット演算子 . を使います

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Student {							// Studentクラスの宣言

		int ID        ;						// フィールド(変数)の宣言
		String Name ;

		public void ShowStudent ( Graphics g, int x, int y) {	// 画面表示用のメソッドを作成
			g.drawString("ID : " + ID,x, y) ;
			g.drawString("Name : " + Name, x, y) ;
		}

	} // End class Student

	public void paint(Graphics g, int ID, String Name, int x, int y) {

		Student Suzuki = new Student() ;		// StudentクラスにSuzukiオブジェクトを追加
		Student Tomo = new Student() ;			// StudentクラスにTomoオブジェクトを追加

		Suzuki.ID = 1 ;					// それぞれのオブジェクトに値を渡す
		Suzuki.Name = "Suzuki" ;
		Tomo.ID = 2 ;
		Tomo.Name = "Tomo" ;

	}
} // End class


--------------------------------------------------------------------------------

で、paint()からクラスのShowStudentを呼び出し画面表示をします。

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Student {							// Studentクラスの宣言

		int ID        ;						// フィールド(変数)の宣言
		String Name ;

		public void ShowStudent ( Graphics g, int x, int y) {	// 画面表示用のメソッドを作成
			g.drawString("ID : " + ID,x, y) ;
			g.drawString("Name : " + Name, x, y) ;
		}

	} // End class Student

	public void paint(Graphics g, int ID, String Name, int x, int y) {

		Student Suzuki = new Student() ;		// StudentクラスにSuzukiオブジェクトを追加
		Student Tomo = new Student() ;			// StudentクラスにTomoオブジェクトを追加

		Suzuki.ID = 1 ;					// それぞれのオブジェクトに値を渡す
		Suzuki.Name = "Suzuki" ;
		Tomo.ID = 2 ;
		Tomo.Name = "Tomo" ;

		Suzuki.ShowStudent(g, 5, 15) ;			// 2つ目、3つ目の引数はShowStudentのなかの
		Tomo.ShowStudent(g, 5, 25) ;			// xとyです
	}
} // End class


--------------------------------------------------------------------------------
◆コンストラクタ

コンストラクタはそのクラスと同一の名前をもつクラスメソッドです。
例えばemployyという名前のクラスを使っているならコンストラクタの名前もemployeeになります。
アプレットでクラスのコンストラクタを定義すると、そのクラス型のインスタンスを生成する度に、自動的にコンスト
ラクタが呼び出されるようになります。

次のステートメントではEmployeeという名前のクラスを定義しています。ここでは、クラスメイト同じEmployeeという
名前のコンストラクタを定義し、その中で各メンバ変数の初期化を行っています。

コンストラクタは値を返しませんが、メソッド名の前にvoidを宣言する必要はありません。

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Employee {

		public int ID ;
		public String Name ;
		public int Salary ;

		public Employee ( int TEMP_ID, String TEMP_Name, int TEMP_Salary ) {
							// コンストラクタです。オブジェクトSuzukiやTomoが
			ID = TEMP_ID ;			// 作成された時に呼び出されます。
			Name = TEMP_Name ;
			Salary = TEMP_Salary ;
		}

		public void ShowEmployee(Graphics g, int x, int y) {

			g.drawString("ID : " + ID, x, y ) ;
			g.drawString("Name : " + Name, x, y + 15 ) ;
			g.drawString("Salary : " + Salary, x, y + 15 ) ;

		}

	}
	public void paint( Graphics g ) {

		Employee Suzuki = new Employee(1, "Suzuki", 10000) ;	//ここでコンストラクタを呼び出す
		Employee Tomo = new Employee(2, "Tomo", 5000) ;		//ここでコンストラクタを呼び出す

		Suzuki.ShowEmployee(g, 5, 15) ;				// 画面出力
		Tomo.ShowEmployee(g, 5, 120) ;
	}

} // End class


--------------------------------------------------------------------------------
◆this キーワードを使う

前例ではコンストラクタの引数の名前にメンバ変数の名前とは異なるものを記述していました。
同じにはならないのでしょうか?というか同じであるべきだと思います。<<混乱を避けるためにも
そこで thisキーワードを使います。
thisキーワードを使うことによってクラスの変数と変数名が同じだとしてもメソッドの引数の中の変数を参照します。
thisはローカルな変数を参照するときに使います。逆にsuperはグローバルな変数を参照するときに使います。


import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Employee {

		public int ID ;				// グローバル変数
		public String Name ;
		public int Salary ;

		public Employee ( intID, String Name, int Salary ) {

			this.ID = ID ;			// thisでローカルメソッドの引数である変数を参照
			this.Name = Name ;
			this.Salary = Salary ;
		}

		public void ShowEmployee(Graphics g, int x, int y) {

			g.drawString("ID : " + ID, x, y ) ;
			g.drawString("Name : " + Name, x, y + 15 ) ;
			g.drawString("Salary : " + Salary, x, y + 15 ) ;

		}

	}
	public void paint( Graphics g ) {

		Employee Suzuki = new Employee(1, "Suzuki", 10000) ;
		Employee Tomo = new Employee(2, "Tomo", 5000) ;

		Suzuki.ShowEmployee(g, 5, 15) ;
		Tomo.ShowEmployee(g, 5, 120) ;
	}

} // End class


--------------------------------------------------------------------------------
◆継承

継承とは既存のスーパークラスの特徴を引き継いで、派生クラス(サブクラス)を作成することです。
下のプログラムで説明するとEmployeeクラスからManagerクラスを派生させることでプログラミングの手間が省けます。
コードをコピーして貼り付けるような同じ記述を2度並べるような無駄も無くなります。

新しくは制させるManagerクラスを作成するにはclassキーワードに続けてクラス名であるManagerを指定し、続けてexte
ndsキーワード、スーパークラスとなるEmployeeを指定します。


import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Employee {

		private String Name ;		// 通常変数はprivateにします。
		private String Position ;	// 他のクラスからの変数への直接アクセスを防ぐ為です
		private double Salary ;		// その代わり関数をpublicにする事で変数を値を変えます。

		public Employee(String Name, String Position, double Salary) {

			this.Name = Name ;
			this.Position = Position ;
			this.Salary = Salary ;

		}
		public String ShowEmployee() {

			return ("Name:" + Name + " Position:" + Position + " Salary :" + Salary ) ;

		}
	} // End class
	class Manager extends Employee {	// Employeeクラスを継承したManagerクラスココが継承!

		private double Bonus ;

		public Manager(String Name, String Position, double Bonus, double Salary) {
							// コンストラクタ
			super(Name, Position, Salary) ;	// Employeeから継承する変数を記述します
			this.Bonus = Bonus ;

		}
		public String ShowManager() {
							// 継承された変数も使える。
			return ("Name:" + Name + " Position:" + Position +
						" Salary :" + Salary + " Bonus :" + Bonus ) ;
		}
	} // End class

	public void paint(Graphics g) {

		Manager Suzuki = new Manager("Suzuki", "CEO", 10000.0, 20000.0) ;

		g.drawString(Suzuki.ShowEmployee(), 5, 15) ;
		g.drawString(Suzuki.ShowManager(), 5, 30) ;
	}

}

コードから解るようにこのアプレットではEmployeeクラスを定義して、Managerクラスをこのクラスから派生させてい
ます。
ココでManagerクラスのコンストラクタに注目して下さい。スーパークラスからクラスを派生させたときには、派生クラ
スのコンストラクタから、スーパークラスのコンストラクタを呼び出さなければなりません。これは単に必要な引数を
指定して、次のようにsuperメソッドを呼び出すだけです。

			super(Name, Position, Salary) ;	// Employeeから継承する変数を記述します

継承とは既存のスーパークラスの特徴を引き継ぐ形で、別のクラスを派生させる事です。既存のクラスデータやメソッ
ドを新しいクラスでも使いたい時に既存のクラスから新しい派生クラスを作成出来ると言うことです。
こうして作成された新しいクラスでは継承元となったクラスのメンバ変数が継承されます。


--------------------------------------------------------------------------------
◆オーバーライド

サブクラスで新しく定義した変数、メソッドが、スーパークラスにすでに存在していたらどうなるか? --- 継承した
ものよりも、サブクラスで定義されたものの方が優先される。
逆に言えば、変数やメソッドはサブクラスから順にスーパークラスをたどっていって、最初に見つかったものが使われ
る。

スーパークラスで定義されたものは、すべてのサブクラスに共通な属性である、というのが原則だが、世の中例外は付
物である(e.g. 「鳥」というクラスには「飛ぶ」という属性があるが、「ペンギン」というサブクラスは「飛べない」
)。また、基本的な振る舞いは同じでも、各サブクラスはその状況に適応して余分な仕事をする、あるいは微妙に振る
舞いを変える場合がある。そのような時にオーバーライドが使われる。



import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	class Employee {

		private String Name ;		// 通常変数はprivateにします。
		private String Position ;	// 他のクラスからの変数への直接アクセスを防ぐ為です
		private double Salary ;		// その代わり関数をpublicにする事で変数を値を変えます。

		public Employee(String Name, String Position, double Salary) {

			this.Name = Name ;
			this.Position = Position ;
			this.Salary = Salary ;

		}
		public String ShowEmployee() {

			return ("Name:" + Name + " Position:" + Position + " Salary :" + Salary ) ;

		}
	} // End class

	class Manager extends Employee {	// Employeeクラスを継承したManagerクラスココが継承!

		private double Bonus ;

		public Manager(String Name, String Position, double Bonus, double Salary) {
							// コンストラクタ
			super(Name, Position, Salary) ;	// Employeeから継承する変数を記述します
			this.Bonus = Bonus ;

		}					// ************************************************
		public String ShowEmployee() {		// このサブクラスが優先されて表示されます
							// 継承された変数も使える。
			return ("Name:" + Name + " Position:" + Position +
						" Salary :" + Salary + " Bonus :" + Bonus ) ;
		}
	} // End class

	public void paint(Graphics g) {

		Manager Suzuki = new Manager("Suzuki", "CEO", 10000.0, 20000.0) ;

		g.drawString(Suzuki.ShowEmployee(), 5, 15) ;
	}

}


--------------------------------------------------------------------------------




//////////////////////////////////////////////////////////////////////////////////////////////////////////
グラフィックスとオーディオ

◆ Graphics クラス
	グラフィックスに関する状態を覚えている。
	色
	文字のフォント
	ペイントモード など
	絵や文字を描くメソッドを持つ。
	直線、矩形、ポリゴン、楕円、弧
	文字
	イメージ
	画面領域のクリア、コピー など
	座標系は、アプレット領域の左上が (0,0) で、右方向と下方向に増えていく。単位はピクセル。




--------------------------------------------------------------------------------
◆ Graphics クラス

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

public class Applet1 extends Applet {

        Font f = new Font("Serif", Font.ITALIC, 24);

        public void paint(Graphics g) {
                g.setFont(f);
                g.setColor(Color.yellow);
                g.fillOval(10, 10, 200, 100);
                g.setColor(Color.red);
                g.drawString("Hello world!", 40, 70);
        }
}


--------------------------------------------------------------------------------

◆ Font クラス
文字の形、大きさなどの情報を覚えている。
フォントの名前
スタイル
大きさ など
ブラウザが動いているシステムに、指定したフォントが用意されていなければならない。指定したフォントが存在しな
い場合、デフォールトのフォントで表示される。次のアプレットで、使用できるフォント名と、その表示例をみること
ができる。


◆ Color クラス
赤、緑、青の3つの成分をそれぞれ 8bit (0〜255) で表す。代表的な色はクラス変数として持っている。
システムによっては限られた色しか表示できない、あるいは同時に表示する色数が制限されている場合がある。指定さ
れた色が表示できない場合、近い色に変換されるかディザリングが行なわれる。


--------------------------------------------------------------------------------
◆ Font クラス Color クラス

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

public class Applet1 extends Applet {
        public void paint (Graphics g) {
                for (int i = 0; i < 4; i++) {
                        for (int j = 0; j < 4; j++) {
	for (int k = 0; k < 4; k++) {
	        g.setColor(new Color(i*64, j*64, k*64));
	        g.fillRect(i*20+10, k*100+j*20+10, 20, 20);
	}
                        }
                }
        }
}


--------------------------------------------------------------------------------
◆ Image クラス

イメージデータを記憶しておく。
ファイルからイメージデータを読み取るには Applet クラスのメソッド getImage を使う
画面にイメージデータを表示するには Graphics クラスのメソッド drawImage を使う



--------------------------------------------------------------------------------
◆ Image クラス
// hoeimage.jpgは各自適当に用意してくださいね

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

public class Applet1 extends Applet {

        Image hoeImage;

        public void init() {
                hoeImage = getImage(getDocumentBase(), "hoeimage.jpg");
        }

        public void paint(Graphics g) {
                g.drawImage(hoeImage, 0, 0, this);
        }
}


--------------------------------------------------------------------------------

◆ play メソッドと AudioClip クラス

単純に音を鳴らすだけなら、Applet クラスの play メソッドを使う。
繰り返して音を鳴らしたり、途中で止めたりするときは、AudioClip クラスを使う。次のメソッドが使える。

	// こんな感じで hoeオブジェクトを作成していて・・・
	AudioClip hoe = getAudioClip(getCodeBase(), "Sample.au") ;

play --- 一度だけ再生する
	hoe.play() ;

loop --- 繰り返し再生する
	hoe.loop() ;

stop --- 再生を止める
	hoe.stop() ;


--------------------------------------------------------------------------------
◆ play メソッドと AudioClip クラス


// classのあるフォルダにSample.auというファイルを各自適当に置いてくださいね
// wavでもよいですよ midでも

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet {

	public void paint(Graphics g) {

		AudioClip audioClip = getAudioClip(getCodeBase(), "Sample.au") ;

		g.drawString("Sound Demo", 5, 15) ;
		audioClip.loop() ;
	}

}

--------------------------------------------------------------------------------




///////////////////////////////////////////////////////////////////////////////////////////////////////////
アニメーション

アプレットで行っている処理は非常に単純です。Javaがアプレットを起動するときには最初にinitメソッドを呼び出し
、そこでメンバ変数を初期化します。
下の例ではinitメソッドで現在のアプレットウインドウの幅と高さを取得しています。initメソッドがその処理を完了す
ると、startメソッドが呼び出されます。startメソッドで移動表示されるメッセージを表示する為のスレッドを生成して
います。さらにこのstartメソッドの中でMarqueeThread.startメソッドを呼び出していますが、この結果、オブジェクト
のrunメソッドが呼び出される事になります。

ブラウザが実行する一連の命令をさしてスレッドと呼びます。アプレットで複雑な処理を行うようになってくると同時に
2つ以上の処理を実行したくなるときがあります。例えば画面上で製品の名前を点滅表示させながら、同時に会社のロゴ
を回転しながら表示させたいというような場合です。
2つ以上のスレッドを同時に実行するアプレットはマルチスレッドアプレットと呼ばれます。

WWWブラウザはあるスレッドから別のスレッドにすばやく処理を切り替えると事で、あたかも複数のスレッドが同時に
実行されているように見せます。
アプレットでスレッドを生成するにはスレッドとして実行したいステートメントを吹くkムオブジェクトをコンストラ
クタに渡してThreadクラスのインスタンスを生成します。
Threadオブジェクトを事項するにはアプレットでThreadクラスのstartメソッドを呼び出します。するとstartメソッド
は指定されたオブジェクトのrunメソッドを呼び出します。

public class Applet1 extends Applet implements Runnable {

アプレット内でスレッドを使うときには、このようにクラスにRunnableインターフェイスを実装するようにアプレット
のクラスの定義を変更する必要があります。これによりクラスはrunメソッドを提供するようになります。

--------------------------------------------------------------------------------
◆ repaint メソッド

import java.awt.* ;
import java.applet.* ;

public class Applet1 extends Applet implements Runnable {

	Thread MarqueeThread = null ;		// Threadオブジェクトをnullで初期化
						// これはThreadオブジェクトをまだ生成していない事を意味し
						// ます。
						// nullで無ければおじぇ区とは存在するということですね
	String Message = "JOKER HOE" ;

	Font font = new Font ("Serif", Font.BOLD, 18) ;

	int x ;
	int y ;

	public void init() {

		x = getSize().width ;		// アプレットの幅と上下中央揃えのための記述
		y = getSize().height / 2 ;

	}
	public void start() {

		if(MarqueeThread == null) {	// オブジェクトが存在するのかを調べる

			MarqueeThread = new Thread (this) ;	// スレッドを生成するときには新しいスレッ
								// ドとして実行させたいステートメントを含む
								// オブジェクトをThreadクラスのコンストラ
								// クタに渡します。
			MarqueeThread.start() ;

		}
	}
        public void stop() {

                if (MarqueeThread != null) {
                        MarqueeThread.stop();
                        MarqueeThread = null;
                }
        }
	public void run() {

		while (true) {

			x = x - 5 ;
			if ( x == 0)
				x = getSize().width ;

				repaint() ;
				try{
					MarqueeThread.sleep(500) ;
				}catch (InterruptedException e ) {
				}
		}
	}
	public void paint(Graphics g) {

		g.setFont(font) ;
		g.drawString(Message, x, y) ;
	}
}

--------------------------------------------------------------------------------


◆ちらつきの防止
アニメーションを表示すると、画像がちらつくことがある。これは、古い絵をいったん消去してから新しい絵を書き込
むので、新しい絵が完成するまでの状態が一瞬見えてしまうからである。
これを防ぐための最も単純な方法は、古い絵全体を消去するのをやめてしまうことである。新しい絵によって古い絵が
完全に上書きされてしまう場合には、わざわざ消去する必要がない。実際に消去を行っているのは、 Applet クラスの
(正確には、そのスーパークラスである Component クラスの) update というメソッドである。これは再描画が必要な
ときに呼び出され、領域を消去してから paint を呼び出す。


--------------------------------------------------------------------------------

public void update(Graphics g) {
        g.setColor(getBackground());
        g.fillRect(0, 0, width, height);
        g.setColor(getForeground);
        paint(g);
}


--------------------------------------------------------------------------------
これを、自分のアプレットでは次のようにオーバーライドする。
--------------------------------------------------------------------------------

public void update(Graphics g) {
        paint(g);
}


--------------------------------------------------------------------------------
update をオーバーライドしない例



--------------------------------------------------------------------------------

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

public class Applet1 extends Applet implements Runnable {

        int x = 50;
        Thread runner;

        public void start() {
                if (runner == null) {
                        runner = new Thread(this);
                        runner.start();
                }
        }

        public void stop() {
                if (runner != null) {
                        runner.stop();
                        runner = null;
                }
        }

        public void run() {
                while (true) {
                        x += 5;
                        if ( x > getSize().width - 50 ) {
	x = 50;
                        }
                        repaint();
                        try {
	Thread.sleep(20);
                        } catch (InterruptedException e) {
                        }
                }
        }

        public void paint(Graphics g) {
                g.setColor(Color.blue);
                g.fillRect(10, getSize().height / 2 - 30,
	                         getSize().width - 20, 60);
                g.setColor(Color.red);
                g.fillOval(x - 20, getSize().height / 2 - 20, 40, 40);
        }
}


--------------------------------------------------------------------------------
update をオーバーライドした例



--------------------------------------------------------------------------------

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

public class Applet1 extends Applet implements Runnable {

        int x = 50;
        Thread runner;

        public void start() {
                if (runner == null) {
                        runner = new Thread(this);
                        runner.start();
                }
        }

        public void stop() {
                if (runner != null) {
                        runner.stop();
                        runner = null;
                }
        }

        public void run() {
                while (true) {
                        x += 5;
                        if ( x > getSize().width - 50 ) {
	x = 50;
                        }
                        repaint();
                        try {
	Thread.sleep(20);
                        } catch (InterruptedException e) {
                        }
                }
        }

        public void update(Graphics g) {
                paint(g);
        }

        public void paint(Graphics g) {
                g.setColor(Color.blue);
                g.fillRect(10, getSize().height / 2 - 30,
	                         getSize().width - 20, 60);
                g.setColor(Color.red);
                g.fillOval(x - 20, getSize().height / 2 - 20, 40, 40);
        }
}


--------------------------------------------------------------------------------
新しい絵を描いても古い絵の一部が残ってしまう場合には、その部分を消去するための処理が必要になることに注意。





///////////////////////////////////////////////////////////////////////////////////////////////////////////
イベント

◆イベントとは
プログラムの実行は定められた順番に従って行われるが、実際の世界ではそれとは関係なくさまざまな事象が起こる。
プログラムがそれに対応するためには、事象が起きたことを検知して、それを処理するためのサブプログラムを起動し
なければいけない。プログラム外で起きる事象のことをイベントと言い、それに対応して起動するサブプログラムをイ
ベントハンドラまたはイベント処理ルーチンと言う。

◆マウスイベント
アプレット領域の中にマウスカーソルがある時、マウスボタンをクリックすると、押した瞬間と離した瞬間にイベント
が起きる。今までに作ったアプレットでもイベントは起きるが、プログラムがイベントに対して無関心であるため、ク
リックしてイベントが起きても何も変化しない。もし、マウスをクリックしたときに表示を変化させたいならば、プロ
グラムはそのイベントに対して「聞き耳を立てる」必要がある。

ファイルの最初に import java.awt.event.* を書く。
クラス名の後ろに implements MouseListener をつける。
init の中で addMouseListener(this) を実行する。
以下のメソッドを定義する。
public void mouseEntered(MouseEvent e)
public void mouseExited(MouseEvent e)
public void mousePressed(MouseEvent e)
public void mouseReleased(MouseEvent e)
public void mouseClicked(MouseEvent e)

マウスクリックで移動方向が変わる。


--------------------------------------------------------------------------------
◆マウスイベント

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class Applet1 extends Applet implements Runnable, MouseListener {

        static final int RADIUS = 20, MARGIN = 50;
        int x = MARGIN, dir = 1;
        Thread runner;

        public void init() {
                addMouseListener(this);
        }

        public void start() {
                if (runner == null) {
                        runner = new Thread(this);
                        runner.start();
                }
        }

        public void stop() {
                if (runner != null) {
                        runner.stop();
                        runner = null;
                }
        }

        public void run() {
                while (true) {
                        if ( x <= MARGIN ) {
	dir = 1;
                        } else if ( x >= getSize().width - MARGIN ) {
	dir = -1;
                        }
                        x += dir * 5;
                        repaint();
                        try {
	Thread.sleep(20);
                        } catch (InterruptedException e) {
                        }
                }
        }


		public void paint(Graphics g) {
                g.setColor(Color.red);
                g.fillOval(x - RADIUS, getSize().height / 2 - RADIUS,
	                         RADIUS * 2, RADIUS * 2);
        }

        public void mouseClicked(MouseEvent e) {
                dir = -dir;
        }

        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}
        public void mousePressed(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {}

}


--------------------------------------------------------------------------------
◆マウスモーションイベント

マウスが動いたときにもイベントが発生する。
ファイルの最初に import java.awt.event.* を書く。
クラス名の後ろに implements MouseMotionListener をつける。
init の中で addMouseMotionListener(this) を実行する。
以下のメソッドを定義する。
public void mouseMoved(MouseEvent e)
public void mouseDragged(MouseEvent e)
マウスカーソルの位置は、引数で渡されるMouseEventクラスのインスタンスに対してgetX, getYメソッドを呼び出すこ
とにより得られる。





--------------------------------------------------------------------------------
◆マウスモーションイベント

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class Applet1 extends Applet
        implements Runnable, MouseListener, MouseMotionListener {

        static final int RADIUS = 20, MARGIN = 50, BLOCKW = 5, BLOCKH = 20;
        int x = MARGIN, dir = 1, mx;
        boolean block = false;
        Thread runner;

        public void init() {
                addMouseListener(this);
                addMouseMotionListener(this);
        }

        public void start() {
                if (runner == null) {
                        runner = new Thread(this);
                        runner.start();
                }
        }

        public void stop() {
                if (runner != null) {
                        runner.stop();
                        runner = null;
                }
        }

        public void run() {
                while (true) {
                        if ( x <= MARGIN ) {
	dir = 1;
                        } else if ( x >= getSize().width - MARGIN ) {
	dir = -1;
                        } else if ( block ) {
	if ( mx < x && x < mx + RADIUS ) {
	        dir = 1;
	} else if ( mx - RADIUS < x && x < mx ) {
	        dir = -1;
	}
                        }
                        x += dir * 5;
                        repaint();
                        try {
	Thread.sleep(20);
                        } catch (InterruptedException e) {
                        }
                }
        }

        public void paint(Graphics g) {
                g.setColor(Color.red);
                g.fillOval(x - RADIUS, getSize().height / 2 - RADIUS,
	                         RADIUS * 2, RADIUS * 2);
                if ( block ) {
                        g.setColor(Color.blue);
                        g.fillRect(mx - BLOCKW, getSize().height / 2 - BLOCKH,
		 BLOCKW * 2, BLOCKH * 2);
                }
        }

        public void mouseEntered(MouseEvent e) {
                block = true;
                mx = e.getX();
        }

        public void mouseExited(MouseEvent e) {
                block = false;
        }

        public void mouseMoved(MouseEvent e) {
                mx = e.getX();
        }

        public void mousePressed(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {}
        public void mouseClicked(MouseEvent e) {}
        public void mouseDragged(MouseEvent e) {}

}


--------------------------------------------------------------------------------


◆キーイベント
キーを押した時、離した時にもイベントが起きる。
ファイルの最初に import java.awt.event.* を書く。
クラス名の後ろに implements KeyListener をつける。
init の中で addKeyListener(this) を実行する。
以下のメソッドを定義する。
public void keyPressed(KeyEvent e)
public void keyReleased(KeyEvent e)
public void keyTyped(KeyEvent e)
押されたキーに対応する文字を知りたい時は、引数で渡された KeyEvent クラスのインスタンスに対し getKeyChar メ
ソッドを呼び出すことにより、 char 型の値を得ることができる。Shift や Control キーが押されたことを知りたい
ときは、マニュアルを参照。

◆ Adapter クラス
Listner インターフェースを implements するためには、使わないメソッドもすべて定義しなければならない。それを
防ぐために、Listner インターフェースをすべて空の状態で定義した Adapter クラスが用意されている。プログラマ
は、必要なメソッドだけをオーバーライドしたサブクラスを作ればよい。
しかし、Adapter のサブクラスを完全に独立したクラスとして作るのはいろいろ手間がかかって面倒である。この場合
は、そのサブクラスは他では使わないということが分かっているので、メインのアプレットのクラスの中に埋め込んで
しまうのが便利である。


--------------------------------------------------------------------------------
◆キーイベント

import java.awt.* ;
import java.applet.* ;
import java.awt.event.* ;
import java.awt.event.KeyEvent ;
import java.awt.event.KeyListener ;

public class Applet1 extends Applet implements KeyListener {

	String KeyPressedEvent = null ;
	String KeyReleasedEvent = null ;
	String KeyTypedEvent = null ;

	public void init() {

		addKeyListener(this) ;
		requestFocus() ;
	}

	public void keyReleased(KeyEvent event) {

		int letter = event.getKeyChar() ;

		if(KeyPressedEvent == null) {

			if (letter == 27 ) // ESC KEy
				KeyReleasedEvent = "Esc keyreleased" ;
			else KeyReleasedEvent = "KeyUp: " + (char) letter ;

		}

		KeyPressedEvent = null ;
		repaint() ;
	}

	public void keyPressed(KeyEvent event) {

		KeyPressedEvent = "Action Key Pressed" ;
		repaint() ;

	}

	public void keyTyped(KeyEvent event) {

		int letter = event.getKeyChar() ;
		KeyTypedEvent = "KeyTyped: " +(char) letter ;
		KeyPressedEvent = null ;
		repaint() ;
	}

	public void paint(Graphics g) {

		if (KeyReleasedEvent != null)
			g.drawString(KeyReleasedEvent, 5, 45) ;
		if (KeyPressedEvent != null)
			g.drawString(KeyPressedEvent, 5, 75) ;
		if (KeyTypedEvent != null )
			g.drawString(KeyTypedEvent, 5, 105) ;
	}

}


///////////////////////////////////////////////////////////////////////////////////////////////////////////
ユーザインターフェース

◆ 基本的な部品
AWT というクラスライブラリには、ボタンやメニューなどのユーザインターフェースを構成する部品(コンポーネント)
と、部品の間でやり取りされるイベントや、部品を画面上に配置する仕組み(レイアウト)が入っている。(JDK 1.2 では
 SWING という新しいクラスライブラリも使えるようになる)
部品は大きく次のように分けられる。

他の部品を「張り付ける」土台となるコンテナ
Panel, Dialog など
ユーザとの入出力を行なうインタラクション部品
Label, Button, Choice など
コンテナの上に部品を張り付ける時は add メソッドを使う。実はアプレット自身もコンテナの一種なので、アプレッ
トにボタンなどの部品を張り付けていくことができる。



--------------------------------------------------------------------------------
◆ 基本的な部品

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class Applet1 extends Applet implements ActionListener {

  int count = 0;
  Label la = new Label("0");
  Button bu = new Button("Click me!");

  public void init() {
    add(la);
    add(bu);
    bu.addActionListener(this);
  }

  public void actionPerformed(ActionEvent e) {
    count++;
    la.setText(Integer.toString(count));
  }

}


--------------------------------------------------------------------------------
◆ レイアウト

add メソッドで張り付けられた部品は、コンテナの中で左から右へと順に配置されていく。他の配置をしたい場合は、
setLayout メソッドによりレイアウトの種類を指定すると、アプレットのサイズや部品の位置関係に合わせて適切な配
置をしてくれる。レイアウトの種類には次のようなものがある。

BorderLayout
CardLayout
FlowLayout
GridBagLayout
GridLayout

--------------------------------------------------------------------------------
◆ レイアウト

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class Applet1 extends Applet implements ActionListener {

  int count = 0;
  Font f = new Font("Serif", Font.BOLD, 24);
  Label la = new Label("0");
  Button plus = new Button("+1"), minus = new Button("-1");

  public void init() {
    plus.setActionCommand("+1");
    plus.addActionListener(this);
    minus.setActionCommand("-1");
    minus.addActionListener(this);
    la.setFont(f);
    plus.setFont(f);
    minus.setFont(f);
    la.setAlignment(Label.CENTER);
    setLayout(new BorderLayout());
    add(la, "Center");
    add(plus, "North");
    add(minus, "South");
  }

  public void actionPerformed(ActionEvent e) {
    if ( e.getActionCommand().equals("+1") ) {
      count++;
    } else {
      count--;
    }
    la.setText(Integer.toString(count));
  }

}

--------------------------------------------------------------------------------
◆ 項目の選択

複数の項目の中から選択する場合には Choice や Checkbox を使う。イベントを受け取るためには、どちらも ItemList
ener を使う。
絵を描くための部品として Canvas が用意されている。アプレットに直接描く場合と違い、レイアウトに従って適当な
位置に配置される。

内部クラスのインスタンスが一つだけの時は、クラス名の宣言を省略し、 new クラス名() の後に直接メソッドを書く
ことができる。以下の例では、canvas クラス paint メソッドをオーバーライドしたサブクラスを無名クラスとして作
っている。ただし、変数は親クラスの型で宣言する(この場合は canvas)ため、オーバーライド以外に新しいメソッド
を作ることはできない。




--------------------------------------------------------------------------------
◆ 項目の選択

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class Applet1 extends Applet implements ItemListener {

  Color selectedColor = Color.red;
  Choice ch = new Choice();
  Canvas ca = new Canvas() {
    public void paint(Graphics g) {
      g.setColor(selectedColor);
      g.fillOval(0,0,50,50);
    }
  };

  public void init() {
    ch.addItem("red");
    ch.addItem("green");
    ch.addItem("blue");
    ch.addItemListener(this);
    ca.setBackground(Color.white);
    setLayout(new BorderLayout());
    add(ch, "North");
    add(ca, "Center");
  }

  public void itemStateChanged(ItemEvent e) {
    String s = (String)e.getItem();
    if ( s.equals("red") ) {
      selectedColor = Color.red;
    } else if ( s.equals("green") ) {
      selectedColor = Color.green;
    } else {
      selectedColor = Color.blue;
    }
    ca.repaint();
  }

}


--------------------------------------------------------------------------------
◆ Checkbox

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class Applet1 extends Applet implements ItemListener {

  Color selectedColor = Color.red;
  CheckboxGroup gr = new CheckboxGroup();
  Checkbox ch1 = new Checkbox("red", true, gr);
  Checkbox ch2 = new Checkbox("green", false, gr);
  Checkbox ch3 = new Checkbox("blue", false, gr);
  Panel pa = new Panel(new FlowLayout());
  Canvas ca = new Canvas() {
    public void paint(Graphics g) {
      g.setColor(selectedColor);
      g.fillOval(0,0,50,50);
    }
  };

  public void init() {
    ch1.addItemListener(this);
    ch2.addItemListener(this);
    ch3.addItemListener(this);
    ca.setBackground(Color.white);
    pa.add(ch1);
    pa.add(ch2);
    pa.add(ch3);
    setLayout(new BorderLayout());
    add(pa, "North");
    add(ca, "Center");
  }

  public void itemStateChanged(ItemEvent e) {
    String s = (String)e.getItem();
    if ( s.equals("red") ) {
      selectedColor = Color.red;
    } else if ( s.equals("green") ) {
      selectedColor = Color.green;
    } else {
      selectedColor = Color.blue;
    }
    ca.repaint();
  }

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////
9 マルチスレッド

◆プロセスとスレッド
UNIX などの OS では、複数のプログラムを同時に走らせることができる。プログラムが走っている状態のことをプロ
セス という。プロセスは互いに独立しているので、たとえ同じプログラムを2個走らせていても、そのあいだでデータ
を共有することはできない。
密接に関係する複数の仕事を行うとき、それぞれの仕事に一つずつプロセスを作ると、プロセス間のデータをファイル
やパイプを通して受け渡さなければならないし、プロセスを切り替えながら仕事をするので、効率が悪い。そこで、一
つのプロセスの中で複数の仕事を並列に行う仕組みを考える。それぞれの仕事を行うものをスレッドという。一つのプ
ロセスの中にある複数のスレッドはデータを共有する。また、スレッドの切り替えはプロセスの切り替えよりも速くで
きるのが普通である。

ボールを動かすアプレットでは、アプレット本体のコントロールと、ボールを動かすのを別のスレッドで行っていた。
インスタンス変数は共有されるので、ボールを動かすスレッドが使う変数も、本体のスレッドが値を設定している。


◆排他制御
複数のスレッドが同じ変数の値を変更するときは、同時に変更しないように気をつける必要がある。
--------------------------------------------------------------------------------

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class IncAndDec1 extends Applet
        implements ActionListener {

        int number;
        Button startButton;
        Label numberLabel;
        IncAndDec1Thread t1, t2;

        class IncAndDec1Thread extends Thread {

                int inc;

                IncAndDec1Thread (int i) {
                        inc = i;
                }

                public void run () {
                        for (int i = 1; i <= 50; i++) {
	int n = number + inc;
	try {
	        sleep(500);
	} catch (InterruptedException e) {};
	number = n;
	numberLabel.setText(Integer.toString(number));
                        }
                }

        }

        public void init () {
                Font f = new Font("SanSerif", Font.BOLD, 24);
                startButton = new Button("Start");
                startButton.setFont(f);
                add(startButton);
                startButton.addActionListener(this);
                numberLabel = new Label("50");
                numberLabel.setFont(f);
                add(numberLabel);
        }

        public void actionPerformed(ActionEvent e) {
                number = 50;
                numberLabel.setText("50");
                t1 = new IncAndDec1Thread(1);
                t2 = new IncAndDec1Thread(-1);
                t1.start();
                t2.start();
        }

}


--------------------------------------------------------------------------------

2つのスレッドがばらばらに読み書きするので、片方のスレッドが書き込んだデータが、もう片方のスレッドが書き込
むデータに上書きされて消えてしまう。



これを防ぐには、片方のスレッドが読み書きしている間、もう片方のスレッドを待たせておく必要がある。そのためにs
ynchronized文が用意されている。括弧の中に指定したオブジェクトに対して、スレッドが同時に一つしか動かないよ
うにする。



--------------------------------------------------------------------------------

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class IncAndDec2 extends Applet
        implements ActionListener {

        int number;
        Button startButton;
        Label numberLabel;
        IncAndDec2Thread t1, t2;

        class IncAndDec2Thread extends Thread {

                int inc;

                IncAndDec2Thread (int i) {
                        inc = i;
                }

                public void run () {
                        for (int i = 1; i <= 50; i++) {
	synchronized(numberLabel) {
	        int n = number + inc;
	        try {
	                sleep(500);
	        } catch (InterruptedException e) {};
	        number = n;
	        numberLabel.setText(Integer.toString(number));
	}
                        }
                }

        }

        public void init () {
                Font f = new Font("SanSerif", Font.BOLD, 24);
                startButton = new Button("Start");
                startButton.setFont(f);
                add(startButton);
                startButton.addActionListener(this);
                numberLabel = new Label("50");
                numberLabel.setFont(f);
                add(numberLabel);
        }

        public void actionPerformed(ActionEvent e) {
                number = 50;
                numberLabel.setText("50");
                t1 = new IncAndDec2Thread(1);
                t2 = new IncAndDec2Thread(-1);
                t1.start();
                t2.start();
        }

}


--------------------------------------------------------------------------------
◆待ち合わせ

複数のスレッドが協力して働く場合、片方のスレッドがある作業を終えるのを別のスレッドが待っていなければならな
いことがある。そのような時には、待つ方のスレッドは適当なオブジェクト(普通は作業に関係のあるオブジェクト) の
wait メソッドを呼び出すことにより、実行を停止する。作業をしたスレッドは、同じオブジェクトのnotify メソッド
を呼び出すことにより、待っているスレッドの実行を再開させる。

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class Applet1 extends Applet
        implements ActionListener {

        int number = 0;
        Button incButton;
        Label numberLabel;
        IncAndDec3Thread t1;

        class IncAndDec3Thread extends Thread {

                public void run () {
                        for (int i = 1; i <= 50; i++) {
	if (number > 0) {
	        synchronized(numberLabel) {
	                number--;
	        }
	        numberLabel.setText(Integer.toString(number));
	} else {
	        try {
	                synchronized(numberLabel) {
	                        numberLabel.wait();
	                }
	        } catch (InterruptedException e) {
	        }
	}
	try {
	        sleep(1000);
	} catch (InterruptedException e) {};
                        }
                }

        }

        public void init () {
                Font f = new Font("SanSerif", Font.BOLD, 24);
                incButton = new Button("Increment");
                incButton.setFont(f);
                add(incButton);
                incButton.addActionListener(this);
                numberLabel = new Label("0");
                numberLabel.setFont(f);
                add(numberLabel);
        }

        public void start() {
                if (t1 == null) {
                        t1 = new IncAndDec3Thread();
                        t1.start();
                }
        }

        public void stop() {
                if (t1 != null) {
                        t1.stop();
                        t1 = null;
                }
        }

        public void actionPerformed(ActionEvent e) {
                synchronized(numberLabel) {
                        if (number++ == 0) {
	        numberLabel.notify();
                        }
                }
                numberLabel.setText(Integer.toString(number));
        }

}


///////////////////////////////////////////////////////////////////////////////
//////
==============================================================================



I-ichirow Suzuki _/_/_/_/_/_/_/_/_/_/_
URL : www.kg-group.com Top Page
Mail : suzuki@kg-group.com
/_/_/_/_/_/_/_/_/_/_/_/_ ICQ : 3743158