Javaとオブジェクト指向プログラミング

Webアプリケーション開発の基礎
~Javaによるアプリケーション開発~
ー2002年10月19・26日(土)ー
Javaとオブジェクト指向プログラミング
神奈川大学工学部 窪谷浩人
e-mail:[email protected]
http://eweb.n.kanagawa-u.ac.jp/~kubotani/Welcome.html
Javaとオブジェクト指向プログラミング
ー第1日目の内容ー
§1. オブジェクト指向プログラミングの基本構造
§2. Javaプログラムの構成要素
§3. Javaを利用したCGプログラミング
描画 & GUI(Graphical User Interface)
「Frame」に
図形を描く・写真を貼る
「Frame」にGUI機能を付け加える
1.
2.
3.
メニューの表示
メニューの選択で「終了」の実行
ダイアログボックスの表示・操作
§4. 総合課題:デジタルアルバムの作成
§1.オブジェクト指向プログラミングの基本構造
「オブジェクト」の発想(1)
従来の考え方
逐次処理(実行する順番に命令を与える)
プログラムカウンタ
メモリアドレス
命令
00000000
00000001
00000002
00000003
00000004
00000005
00000006
「コンピュータの気持ち」でプログラミング
「オブジェクト」の発想(2)
「オブジェクト」の発想
情報処理(入力⇒内部状態の変化⇒出力) する
オブジェクト(=物)達が連動する
と説明された上で
「どちらが元々のモデルに近いかい?」
と言われると
次のように想像してしまう。
「オブジェクト」の発想(3)
「オブジェクト」って、こういうシミュレーション!?
経済動向の予測:
\110
人間のコピーロボット(オブジェクト)を作り、
初期の資金を与え経済活動させる。
\150
\90
\100
\200
\75
\500
オブジェクト指向プログラミングの基本構造(1)
オブジェクト
特性:変数(内部状態)・メソッド(機能・関数)
オブジェクトのメンバ
メソッド
メソッド
変数
メソッド
メソッド
・内部状態を表す変数は外から直
接見える(参照できる)部分もある
・メソッドを通しても外から内部状態
を参照・変更可能である
・メソッドは内部状態を参照している
ので、内部状態によって機能が変わ
ることもある
オブジェクト指向プログラミングの基本構造
(2)
「クラス」・「インスタンス」(実例)とオブジェクト間の連携
鋳型
自動車クラス
人間クラス
六角太郎
(インスタンス
名)
神大花子
(インスタンス
名)
鋳型
運転
(メッセージ)
義経号
(インスタンス
名)
「クラス」:類型化され鋳型として働くプログラム・モジュール。
「インスタンス」:クラスの変数・メソッドはインスタンスという実在を創って利
用する(除クラス変数・クラスメソッド)。
(注)サブルーチン副プログラムは、引用されて始めてメモリ領域が確保さ
れる点で似ているものの、return文で領域が開放される。
他方、インスタンスは実在として存在し続ける。
オブジェクト指向プログラミングの基本構造
(3)
「オブジェクト指向」のプログラミング法
• 継承
猿クラス
チンパンジークラス
スーパークラス
人間クラス
サブクラス
サブクラスでは、スーパークラス(既存のプログラム)のメンバをそのまま引き
継いだ上で、オリジナルなメンバを追加・上書き修正し利用する。
ゼロから新作する必要がない。
• 抽象クラス(例AbstractButtonクラス)
具体的処理を記述せずメソッド名や引数のみからなる抽象メソッドを含むクラス
具体的処理は、継承を受けたサブクラスを利用者が創ってそこで定義する
作成されたサブクラスを束ねて類型化する役割
オブジェクト指向プログラミングの基本構造
(4)
「オブジェクト指向的」のプログラミング法
・インターフェースのインプリメント:
既存のプログラムを応用する第2の方法
Javaでは継承の親は一つ(「単一継承」)。
他方、複数のインターフェースのインプリメントは可能。
継承
スーパー
クラス
インプリメント
定数の定義
抽象メソッドの定義
インター
フェース
抽象メソッドの
サブクラスA
サブクラスB
#気分としては、ヘッダーファイルのincludeのような感じ
実体定義
非オブジェクト指向プログラミング
継承(再定義可能)、
との比較
メソッドやコンストラ
非オブジェクト指向
オブジェクト指向
サブルーチン副プログラム
による
モジュール化(カプセル化)
ライブラリの利用
クタの多重定義、
アクセスレベル
機能の追加拡張
変数の受け渡し が容易で、
変数の隠蔽
既存プログラムの有効活用可能
機種依存のない
(Windows, X-Window, MacOS X)
Windowプログラミング可能
時系列的な処理が基本
マルチスレッドによる並列処理
#ただし、コンピュータのハードウェアはノイマン型な
ので、マルチスレッドは仮想的な並列処理である。プ
ログラミング手法としての存在意義である。
機種依存のない窓プログラミング
サンプルプログラムMenuFrame.javaの実行結果
Windows 98
MacOS 8.1
§2. Javaプログラムの構成要素(1)
• クラスの書き方
クラス宣言
class クラス名 extends スーパークラス名 implements インターフェース名
{
メンバ変数の定義
・・・
コンストラクタの定義
クラス本体
・・・
メソッドの定義
・・・
}
Javaプログラムの構成要素(2)
• メンバ変数の定義
[アクセスレベル] [修飾子]データ型 変数名[ = 初期値];
#データ型:基本データ型:整数・実数・一文字・真偽値
参照データ型:reference(ポインタ)が入るので文字列や
インスタンスも宣言可能
• メソッドの定義
[アクセスレベル] [修飾子] 戻り値データ型 メソッド名(データ型 引数名)
{
メソッド本体
}
例: public static void main(String args [] ){….}
どのクラスからもアクセス可能で(public)、インスタンスを作らなくても実行でき
て(static,クラスメソッド)、戻り値はなく(void)、引数は文字列の配列。
# 引数列が異なるメソッドを同じメソッド名で定義できる(「多重定義」(Overload))。
Javaプログラムの構成要素(3)
• コンストラクタの定義
インスタンスの生成要求があった時に自動的に(必ず)実行され、
初期のインスタンス状態の設定に利用される。
[アクセスレベル] クラス名(データ型 引数名)
{
コンストラクタ本体
}
形の上ではメソッドの定義と似ているが、名前の部分がクラス名と同一。戻り値もない。
• インスタンスの生成:new演算子
new クラス名(コンストラクタの引数);
引数はコンストラクタに引き渡され、生成されるインスタンスの初期状態を設定
する
Javaプログラムの構成要素(4)
Staticメンバと非Staticメンバ
クラスはメンバとして変数・メソッドを備えている
Staticメンバ(修飾子「static」を付けて定義)
クラス変数(例:Math.PI)
クラスメソッド(例:Math.sqrt)
・「クラス名.メンバ名」で参照・実行される
New
(クラスメソッドはサブクラスに継承されない)。
・クラスメソッドの定義中には非Staticメンバは
現れない(インスタンスを生成し利用することは可能)。
非Staticメンバ(定義文に「static」がない)
インスタンス変数・インスタンスメソッド
・クラスからインスタンスを創って
変数:A.b
利用する
メソッド:A.getArea
・「インスタンス名.メンバ名」で参照・
実行される
インスタンスA
クラス
static int a;
int b;
static void main( )
double getArea( );
New
New
変数:B.b
メソッド:B.getArea
インスタンスB
変数:C.b
メソッド:C.getArea
インスタンスC
「オブジェクト指向」的プログラミング(1)
ーオブジェクト(インスタンス)の生成ー
Triangleクラス
AreaMainクラス
変数:a, b, c (辺長)
メソッド:Main
メソッド:getArea(面積の計算)
printValue
辺長の設定
辺長の参照
面積の値
インスタンス t1
インスタンス t2
サンプルプログラムAreaMain.java(1/2)
class Triangle
{
double a, b, c;
void printValue()
{
System.out.println(“三角形の値(" + a + "," + b + "," + c + ")" );
}
double getArea()
{
double p;
double S;
Systemクラスのクラス変数outに記
録されているクラス(PrintStream)
のインスタンスメソッドprintlnを実
行する
p=(a+b+c)/2.0;
S=Math.sqrt(p*(p-a)*(p-b)*(p-c));
return S;
}
}
サンプルプログラムAreaMain.java (2/2)
class AreaMain
{
public static void main( String args [])
{
Triangle t1 = new Triangle();
Triangle t2 = new Triangle();
t1.a = 3.0; t1.b = 4.0; t1.c = 5.0;
t2.a = 1.0; t2.b = 1.0; t2.c = 1.0;
new演算子によるTriangleインス
タンスの生成
各インスタンスの変数の設定
t1.printValue();
t2.printValue();
各インスタンスのメソッドの実行
double s1 = t1.getArea();
double s2 = t2.getArea();
System.out.println( "t1の面積は" + s1 + ", t2の面積は" + s2 + "です");
}
}
「オブジェクト指向」的プログラミング(2)
ー変数の隠蔽-
アクセスレベル
メンバ変数:どのクラスに参照・変更させるか
メソッド・コンスタラクタ:他のどのクラスが実行できるか
アクセスレベル
オプション
同じ
クラス
private
○
サブ
クラス
すべての
クラス
×
○
protected
×
○
public
なし
同じ
パッケージ
○
(注)
○
×
(注)同じパッケージにあればサブクラスであってもアクセス許可される。
サンプルプログラムAreaMain2.java
class Triangle{
private double a, b, c;
アクセスレベルprivate
多クラスからの参照禁止
void setValue(double a, double b, double c){
this.a = a;
this.b = b;
this.c = c;
}
・・・ }
class AreaMain{
public static void main( String args []){
Triangle t1 = new Triangle();
Triangle t2 = new Triangle();
t1.setValue( 3.0, 4.0, 5.0);
t2.setValue( 1.0, 1.0, 1.0);
} ・・・ }
直接Triangleインスタンス
の変数を参照できない
-setValueメソッドを介在さ
せてメンバ変数を設定
「オブジェクト指向」的プログラミング(3)
ー継承ー
Triangleクラス
VolumeMainクラス
変数:a, b, c (辺長)
メソッド:Main
メソッド:getArea(面積の計算)
底辺長の設定
高さの設定
printValue
底辺長・高さの
参照
継承
体積の値
New
Tetrahedronクラス
変数:a, b, c (底辺長),h(高さ)
メソッド:getArea(底面積の計
算)
getVolume(体積の計
算)
New
printValue
サンプルプログラムVolumeMain.java (1/2)
class Triangle{
変数をサブクラスにも公開する
protected double a, b, c;
void setValue(double a, double b, double c){ ・・・ }
void printValue(){ ・・・ }
double getArea(){ ・・・ } }
クラスTriangleを継承
class Tetrahedron extends Triangle{
private double h;
変数h(高さ)をメンバに追加
void setValue(double a, double b, double c, double h){
スーパークラスのメソッド
super.setValue( a, b , c);
底辺の設定にはスー
setValueは再定義により上
this.h = h;
パークラスのメソッド
書き(Override)される
}
setValueを使う
void printValue(){
System.out.println("4面体の値(" + a + "," + b + "," + c + "," + h + ")" );
}
double getVolume(){
double S;
double V;
S = super.getArea();
底辺の面積Sの計算にはスーパー
V = S * h /3.0;
クラスのメソッドを使う
return V;}
}
サンプルプログラムVolumeMain.java (2/2)
class VolumeMain
{
public static void main( String args []){
Tetrahedron t1 = new Tetrahedron();
Tetrahedron t2 = new Tetrahedron();
t1.setValue( 3.0, 4.0, 5.0, 4.0);
t2.setValue( 2.0, 2.0, 2.0, 2.0);
t1.printValue();
t2.printValue();
double s1 = t1.getArea();
double v1 = t1.getVolume();
double s2 = t2.getArea();
double v2 = t2.getVolume();
System.out.println( "t1の底面積は" + s1 + "、体積は" + v1 + "です");
System.out.println( "t2の底面積は" + s2 + "、体積は" + v2 + "です");
}
}
Javaを利用したCGプログラミング(1)
標準パッケージJava API(Application Programming Interface)
パッケージ名
java.applet
java.awt
java.io
java.lang
java.math
java.net
java.rmi
java.security
java.sql
java.text
java.util
用途
Javaアプレット作成用
GUI機能(AWT=Abstract Window Toolkit)
I/O機能
オブジェクト・文字列・数字などの基本要素定義
数学的な関数の処理など
ネットワークプログラミング用
ネットワーク上でオブジェクトを操作
セキュリティ管理用
関係型データベースへのアクセス用
テキスト・日付・数値などを国・地域に依存しないデータとして処理
乱数・ハッシュテーブル・ベクトルの取り扱い
Javaを利用したCGプログラミング(2)
AWTからの継承の例
1. 描画プログラミング
1.1 「Frame」に基本図形を描く
1.2 画像ファイルを貼る
2. GUIプログラミング
「Frame」にGUI機能を付け加える
2.1 メニューの表示
2.2 メニューの選択で「終了」の実行
2.3 ダイアログボックスの表示・ボタンのクリック処理
1. Javaによる描画プログラミング
出発点:Windowを表示するBasicFrameクラス
(BasicFrame.java)
java.awtパッケージのインポート(他のパッケージ内のクラスを利用可能にする)
import java.awt.*;
java.awt.Frameクラスからの継承
class BasicFrame extends Frame
{
public static void main(String args[])
{
BasicFrame BF=new BasicFrame();
クラスメソッドmainが
(static)最初に外から
起動される(public)
戻り値:無し
BF.setSize( 580, 460 );
BF.setVisible( true );
}
}
引数:文字列の配列
new演算子による
インスタンスの生成
1.1 基本図形の描画(1)
描画メソッドpaintの再定義(LineFrame.java)
import java.awt.*;
class LineFrame extends Frame
{
public void paint(Graphics g){
g.drawLine(70,50,490,120);
}
public static void main(String args [] )
{
LineFrame LF=new LineFrame();
LF.setSize(580,460);
LF.setVisible(true);
}
}
BasicFrameに追加した
部分-Frameクラスから
継承しているメソッド
paintを再定義
LineFrameインスタンス
LFの生成をきっかけに
paintメソッドを実行
1.1 基本図形の描画(2)
(Frameの)paintメソッドの実行
public void paint(Graphics g)
{
g.描画命令( 引数 );
}
Graphicsオブジェクトのインスタンスgを生成
Graphicsオブジェクトは、描画領域・色・フォントなどの情報をオブジェクト化
したもの
Graphicsオブジェクトのメソッドで属性設定を行う
•
•
•
•
g.drawLine(int x1, int y1, int x2, int y2) :(x1,y1)(x2,y2)間の直線
g.drawRect(int x, int y, int width, int height) :左上角(x,y)の矩形
g.drawOval(int x, int y, int width, int height) :左上角(x,y)の楕円
g.setColor(Color c) :色の設定 などなど
Colorクラスのインスタンスc(色種もオブジェクト)
1.1 他の図形(Javaプログラム実例)
Javapg03_フレームの表示とグラフィクス.ppt
(By. Uchida)pp.269-298, 参照
上記へ飛ぶ
1.2 画像ファイルの描画(1)
サンプルプログラムJPegFrame.java
import java.awt.*;
class JPegFrame extends Frame
{
public void paint(Graphics g)
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image =toolkit.getImage( "flower.jpg" );
g.drawImage( image, 30, 60, this);
}
public static void main(String args [] )
{
JPegFrame JF = new JPegFrame();
JF.setSize( 630, 450);
JF.setVisible(true);
}
}
BasicFrameに
追加した部分
1.2 画像ファイルの描画(2)
1. 画像データを持つImageオブジェクト作成
Toolkit toolkit =Toolkit.getDefaultToolkit();
Image image =toolkit.getImage( “ファイル名” );
Imageクラスとは
java.awt.Imageクラスのこと
java.awt.Toolkitクラスの利用
java.awt.Toolkitクラスの利用
Toolkitクラスは、Javaが提
供するGUIコンポーネントと
個々の環境における
Windowシステムとの仲立
ちをする
2. Imageオブジェクトの描画
GraphicsクラスのdrawImageメソッドの利用
g.drawImage(Image image, int x, int y, ImageObserver obs)
g.drawImage(Image image, int x, int y, int width, int height, ImageObserver obs) 等
#1. (x,y)はイメージの左上を原点とする座標、
width, heightはイメージの矩形の幅、高さ
2. ImageObserverは、イメージのロード終了の通知を受けるオブジェクト。
画像を描かせている場合、通常、そのコンポーネント自身、つまり、thisとする。
2. JavaによるGUIプログラミング
ー 「Frame」にGUI機能を付け加えるー
具体例
1 メニューの表示
プログラミングの要素
GUI要素の追加
Java.awt(サブ)パッケージの継承
により利用
2 メニューで「終了」の実行 イベント処理
3 ダイアログボックスの
表示・ボタンのクリック
GUI要素のレイアウト
1.メニューの表示
「メニュー」の要素と構造
フレーム
フレーム
追加(setMenuBarメソッド)
メニューバー
メニューバー
追加(addメソッド)
メニュー
メニュー
追加(addメソッド)
メニュー項目
メニュー項目3つ
サンプルプログラムMenuFrame.java
(1/3)
import java.awt.*;
class MenuFrame extends Frame {
public MenuFrame()
{
super();
setMenu();
}
・・・・
private void setMenu(){ ・・・
コンストラクタ
-インスタンスが生成された時、スー
パークラスFrameのコンストラクタとこの
(this)クラスのsetMenuメソッドを実行
}
setMenuメッソッドの定義
public static void main(String args[])
{
MenuFrame MF = new MenuFrame("Menu Sample");
MF.setSize(580,460);
本体のクラスからインスタンスを
MF.setVisible(true); }
生成する今までと同じmainメソッド
}
サンプルプログラムMenuFrame.java (2/3)
setMenuメソッドの定義
private void setMenu(){
MenuItem NewCreate = new MenuItem("新規作成") ;
MenuItem OpenFile = new MenuItem("開く");
MenuItem FinalExit =new MenuItem("プログラム") ;
Menu FileMenu = new Menu("ファイル");
FileMenu.add( NewCreate );
FileMenu.add( OpenFile );
FileMenu.add( FinalExit );
Menu EditMenu = new Menu("編集");
EditMenu.add( new MenuItem("切り抜き") );
EditMenu.add( new MenuItem("コピー") );
EditMenu.add( new MenuItem("貼り付け") );
MenuItemに明示的な名前
を付け、それを引数として
MenuインスタンスEileMenu
にぶら下げる
MenuItemインスタンスを次々
生成させながらMenuインスタ
ンスEditMenuにぶら下げる
MenuBar mb = new MenuBar();
MenuBarインスタンスmbにMenuイン
mb.add(FileMenu);
スタンスを登録する
mb.add(EditMenu);
this.setMenuBar(mb);
}
この(this)クラス、MenuFrameにmbをMenuBarとして追加する
サンプルプログラムMenuFrame.java (3/3)
多重定義コンストラクタ
(引数が違うものを並列定義)
public MenuFrame()
{
super();
setMenu();
}
public MenuFrame(String title)
{
super(title);
setMenu();
}
明示的に定義しないとスーパークラス
のコンストラクタsuper()のまま。
setMenuによるオリジナル機能の追加
引数を付けてインスタンス生成
を行うためのコンストラクタを
追加(「多重定義」(Overload))
GUIのイベント処理
因果律の流れ
オブジェクト指向的理解
イベントソース・オブジェクト
ボタン・メニュー項目
ユーザの操作
ボタンのクリック・メニューの選択
キー入力・ウィンドウ状態の変更など
イベント・オブジェクト
ボタンがクリックされること
メニューが選択されること
キー入力があること
ウィンドウの状態が変化すること
イベントの発生
イベントリスナー・オブジェクト
処理の開始
処理内容を記
述したメソッド
2.メニューで「終了」の実行(1)
ActionListenerクラス
フレームを描画するクラス内で生成
される「メニュー項目」インスタンスに
addActionListenerメソッドを実行さ
せりリスナーインスタンスを指定
インプリメント
リスナーインターフェース
をインプリメントしたクラス
として作成
ClosingActionListener
MenuFrameクラス
クラス
コンストラクタ
イベント情報に伴い実行す
る処理をメソッドとして記述
MenuItem
インスタンス
ActionEvent
の仲介
ClosingActionListner
インスタンス
2.メニューで「終了」の実行(2)
(1)「終了」の実行
(I)イベントリスナークラスの定義
(II)必要なイベントメソッドの記述
public void actionPerformed(ActionEvent evt)
{
「終了」のための処理の記述;
}
(2)メニューの選択=イベントソース
(III)イベントソースへのリスナーの登録
FinalExit:イベントソースインスタンス
CAL:イベントリスナーインスタンス
MenuItem FinalExit = new MenuItem("プログラムの終了");
ClosingActionListener CAL = new ClosingActionListener();
FinalExit.addActionListener(CAL );
サンプルプログラムMenuExitFrame1.java (1/2)
import java.awt.*;
import java.awt.event.*;
class MenuExitFrame extends Frame
{ ・・・・ }
イ
ベ
ン
ト
リ
ス
ナ
ー
オ
ブ
ジ
ェ
ク
ト
java.awt.eventパッケージも使うので追加
インターフェースを利
用してイベント処理の
機能を追加
class ClosingActionListener implements ActionListener
{
ActionListnerインターフェース
public void actionPerformed(ActionEvent evt) の抽象メソッドをここで具体化
(Override)
{
String MenuName = evt.getActionCommand();
if( MenuName.equals("プログラムの終了") )
ActionEventにソースイ
{
ベント情報を尋ねる
System.exit(0);
}
Stringオブジェクトの
equalsメソッドで照合
}
}
サンプルプログラムMenuExitFrame1.java(2/2)
class MenuExitFrame extends Frame
{
public MenuExitFrame(){ ・・・・ }
private void setMenu()
{
MenuItem FinalExit = new MenuItem("プログラムの終了");
ClosingActionListener CAL = new ClosingActionListener();
FinalExit.addActionListener( CAL );
・イベントリスナー・インスタンスの生
成
Menu FileMenu = new Menu("ファイル");
FileMenu.add( FinalExit );
MenuBar mb = new MenuBar();
mb.add(FileMenu);
this.setMenuBar(mb);
}
・MenuItemインスタンスが発生する
イベント(メニュー項目の選択)をイ
ベントリスナー・インスタンスと結ぶ
サンプルプログラムMenuExitFrame2.java (1/2)
Frameがイベントリスナーオブジェクト
import java.awt.*;
import java.awt.event.*;
ActionListenerをFrameがimplement
class MenuExitFrame extends Frame implements ActionListener
{
public MenuExitFrame(){ ・・・ }
private void setMenu(){ ・・・ }
イベントリスナー役としてのメ
ソッドの定義
public void actionPerformed(ActionEvent evt)
{
String MenuName = evt.getActionCommand();
if( MenuName.equals("プログラムの終了") )
{ System.exit(0); }
}
public static void main(String args[]){ ・・・ }
}
サンプルプログラムMenuExitFrame2.java (2/2)
import java.awt.*;
import java.awt.event.*;
class MenuExitFrame extends Frame implements ActionListener
{
public MenuExitFrame(){ ・・・ }
private void setMenu(){
MenuItem FinalExit = new MenuItem("プログラムの終了");
FinalExit.addActionListener( this );
Menu FileMenu = new Menu("ファイル");
FileMenu.add( FinalExit );
MenuBar mb = new MenuBar();
mb.add(FileMenu);
this.setMenuBar(mb);}
public void actionPerformed(ActionEvent evt){ ・・・ }
public static void main(String args[]){ ・・・ }
}
・MenuItemインスタンスが発
生するイベント(メニュー項目
の選択)をイベントリスナー・
インスタンスと結ぶ
(注)ここでは、イベントリス
ナー・インスタンスは自分自
身のインスタンス(this)
イベント処理の実装の考え方
イベントソース イベントオブジェクト
ウインドウの操作
イベントリスナー
メニューの選択
意図した処理の開始
ダイアローグのボタン
キー入力
ActionEvent
WindowEvent
MouseEvent etc.
イベントソースオブジェクトとイベントリスナーオブジェクトとは多対
1の関係。そこで、時間列に反して、実装はイベントリスナーから
取り掛かる方が理解は容易。
2.メニューで「終了」の実行(3)
リスナークラスの構築別法
問題の所在:リスナーインターフェースが複数のリスナー
メソッドを抽象メソッドとして準備している場合があり、
インプリメントによりこれを利用するするためにはすべての
抽象メソッドを明示的に具体化しなければならない。
アダプタークラスの利用
アダプタークラスのサブクラスとして
リスナークラスを構築すれば、必要な
抽象メソッドの具体化だけでよい。
例:
リスナー
インターフェース
アダプター
クラス
継承
インプリメント
ActionListener:リスナーメソッド1個:アダプターなし
WindowListener:リスナーメソッド7個:WindowAdapter
お手製の
リスナークラス
サンプルプログラムMenuExitFrame3.java
import java.awt.*;
import java.awt.event.*;
class MenuExitFrame extends Frame
{
public MenuExitFrame(){ ・・・ }
private void setMenu() { ・・・ }
public static void main(String args[])
{ MenuExitFrame MF = new MenuExitFrame("Menu Sample (Exit)");
ClosingListener CL = new ClosingListener();
・イベントリスナー・インスタン
MF.addWindowListener( CL );
スの生成
MF.setSize(580, 460);
・Frameサブクラスのインスタ
MF.setVisible(true);
ンス(MF)が発するイベント(閉
}
じるボタンクリック)をイベント
リスナー・インスタンスと結ぶ
}
class ClosingListener extends WindowAdapter
{
WindowAdapterを継承して
public void windowClosing(WindowEvent e)
イベントリスナーを導入
{ System.exit(0);}
}
2.メニューで「終了」の実行(4)
イベントを発したMenuItemインスタンスをメ
ニュー項目名で照合することが出来ない
場合はどうするの?
2.メニューで「終了」の実行(5)
イベント・ソースの判定法
getActionCommand( ): ActionEventのコマンド名を返す
public void actionPerformed(ActionEvent evt)
{
if( evt.getActionCommand().equals("プログラムの終了") )
{
System.exit(0); }
}
getSource( ): イベントが起こったオブジェクトを返す
public void actionPerformed(ActionEvent evt)
{
if( evt.getSource() == FinalExit )
{
System.exit(0); }
}
MenuItemインスタンス名
問題:どうやってイベント・ソースの情報をリスナーに教える
解決策1:リスナーをフレームクラス自身が担う
サンプルプログラムMenuExitFrame4.java
class MenuExitFrame extends Frame implements ActionListener{
MenuItem FinalExit;
ローカル変数からメンバ変数へ格上げ
・・・・
private void setMenu(){
// MenuItem FinalExit = new MenuItem("プログラムの終了");
FinalExit = new MenuItem("プログラムの終了");
FinalExit.addActionListener( this );
FileMenu.add( FinalExit );}
イベントソースとリ
スナーを同一のク
ラスが担う
public void actionPerformed(ActionEvent evt){
// if( evt.getActionCommand().equals("プログラムの終了") )
if( evt.getSource() == FinalExit )
{ System.exit(0);} }
解決策2:独立リスナークラスがイベントソー
スのメンバ変数を参照可能にする
サンプルプログラムMenuExitFrame5.java
Frameインスタンスを引数としてリス
class MenuExitFrame extends Frame{
public MenuExitFrame(){ ・・・ } ナーインスタンスに渡す
private void setMenu(){
FinalExit = new MenuItem("プログラムの終了");
ClosingActionListener CAL = new ClosingActionListener(this);
FinalExit.addActionListener( CAL );
・・・}
public static void main(String args[]) { ・・・ }
}
class ClosingActionListener implements ActionListener{
MenuExitFrame MF;
コンストラクタ
public ClosingActionListener(MenuExitFrame f )
{ MF = f; }
public void actionPerformed(ActionEvent evt){
//if( evt.getActionCommand().equals("プログラムの終了") )
if( evt.getSource() == MF.FinalExit )
{ System.exit(0);}
}
}
3.確認ダイアログの作成(1)
ダイアログの仕様
1
ダイアログボックスのデザイン
プログラミングの要素
Dialogクラスの継承
(DialogクラスはFrameクラスと違
いメニューを載せられない)
GUI要素のレイアウト
2
メニューの「終了」選択で
ダイアログボックスが現れる
イベント処理
3
「OK」ボタンでプログラム終了
イベント処理
「CANCEL」ボタンでダイアログボッ
クスを閉じる
GUIコンポーネントの配置
土台として
必須
レイアウトマネージャ
コンテナの中でのGUIコンポーネ
ントの配置を管理するクラス
トップレベルコンテナ
setLayout
add
Frame
Dialog
Applet
中間コンテナ
setLayout
add
Panel
JScrollPane
JSplitPane等
アトミックコンポーネント
・コンポーネントの固有の大きさで
横一列に配置
FlowLayout・BoxLayout
・コンテナ内で取りえる最大の大きさ
に調整してコンポーネントを配置
BorderLayout
・どのコンポーネントも同じ大きさで
格子状に配置
GridLayout
Label
Button
JCheckBox等
*コンテナ毎にデフォルトのレイアウト
マネージャが設定されている。別のレ
イアウトマネージャを利用するには
setLayoutで明示的に設定
サンプルプログラムDialogSampleFrame.java(1/6)
class ConfirmDialog extends Dialog implements ActionListener
{
Frame parent;
Button OK_Button;
メンバ変数の定義
Button CANCEL_Button;
dialogClosing dC;
コンストラクタの定義開始
public ConfirmDialog(Frame f)
{
super(f,"確認",true); Dialogクラスの引数(第1:オーナーフレーム;第
this.parent = f;
2:タイトル;第3:ture→モーダルダイアログ選択)
Label MESSAGE = new Label("終了してよろしいですか?");
OK_Button = new Button("OK");
ラベルとボタンの作成
CANCEL_Button = new Button("CANCEL");
サンプルプログラムDialogSampleFrame.java(2/6)
GUIコンポーネントをコンテナに次々積み重ねていく
Panel BUTTONS = new Panel();
BUTTONS.add(OK_Button);
BUTTONS.add(CANCEL_Button);
ボタン2個をパネルに貼り付け一まと
めにする
Panel TotalPanel = new Panel();
ボタンをまとめたパネル
とラベルをパネルに貼り
TotalPanel.setLayout( new GridLayout(2,1));
付ける
TotalPanel.add( MESSAGE );
TotalPanel.add( BUTTONS );
PanelインスタンスBUTTONS
は更に別のPanelインスタンス
this.setLayout( new FlowLayout() );
に載せることが出来る
this.add( TotalPanel );
this.setSize( 200, 100);
FlowLayoutによる配置で最
終的なパネルをダイアログに
・・・・・
}
コンストラクタ定義終わり
}
ダイアログのサブクラスの定義終わり
貼り付ける
3.確認ダイアログの作成(2)
オブジェクト間の関係
Dialogクラス
Frameクラス
ActionEvent
の仲介
DialogSample
Frameクラス
ActionEvent
の仲介
Confirm
Dialogクラス
MenuItem
WindowEvent
の仲介
WindowEventの仲介
Window
Adapter
windowClosing
クラス
:継承(クラス間の関係)
dialogClosing
クラス
:Eventを仲介しての
インスタンス間の関係
サンプルプログラムDialogSampleFrame.java(3/6)
class ConfirmDialog extends Dialog implements ActionListener
{
CconfirmDialogインスタン
Frame parent;
スをイベントリスナーにする
Button OK_Button;
Button CANCEL_Button;
コンストラクタ内で生
dialogClosing dC;
成されたインスタンス
public ConfirmDialog(Frame f){ ・・・ }
を利用したいので内
部変数ではなくメンバ
public void actionPerformed(ActionEvent evt)
変数にしておく
{
if( evt.getSource() == OK_Button ){
dsipose:Dialogの廃棄
dispose();
システム終了
System.exit(0);
}
else if( evt.getSource() == CANCEL_Button ){
dispose();
}
}
}
サンプルプログラムDialogSampleFrame.java(4/6)
class ConfirmDialog extends Dialog implements ActionListener
{
OK_Button, CANCEL_Buttonは他
Frame parent;
メソッドが利用できるようにコンストラ
Button OK_Button;
クタの内部変数ではなくメソッド変数
Button CANCEL_Button;
になっている
dialogClosing dC;
public ConfirmDialog(Frame f){
GUIコンポーネントの貼り付け命令群
OK_Button.addActionListener(this);
CANCEL_Button.addActionListener(this);
・・・・
OK_Button,CANCEL_
Buttonの発するイベント
にリスナーとしての
ConfirmDialogを登録
}
public void actionPerformed(ActionEvent evt){
if( evt.getSource() == OK_Button ){ ・・・}
else if( evt.getSource() == CANCEL_Button ){ ・・・ }
}
}
サンプルプログラムDialogSampleFrame.java(5/6)
class dialogClosing extends WindowAdapter{
DialogWindowのタイトルバー上
Dialog d;
の閉じるボタンを有効にするため
WindowAdapterクラスを定義する
public dialogClosing(Dialog ad){
d = ad;
}
public void windowClosing(WindowEvent e){
d.dispose();
}
}
class ConfirmDialog extends Dialog implements ActionListener{
・・・
dialogClosing dC;
public ConfirmDialog(Frame f){
Dialogサブクラスのインスタン
・・・・・
ス生成時にdialogClosingイン
dC = new dialogClosing(this);
スタンスを生成させイベントリス
this.addWindowListener(dC) ; ナーとして登録しておく
}
public void actionPerformed(ActionEvent evt){ ・・・ }
}
サンプルプログラムDialogSampleFrame.java(6/6)
class DialogSampleFrame extends Frame implements ActionListener
{
MenuItem FinalExit;
メニューの選択でプログラムを終了さ
public DialogSampleFrame(){ ・・・ } せるのではなく、今回は、ダイアログ
をインスタンスとして生成させる
public void actionPerformed(ActionEvent evt){
if( evt.getSource() == FinalExit )
{
ConfirmDialog dlg = new ConfirmDialog(this);
dlg.setVisible(true);
ダイアログをインスタンス
}
として生成
}
ダイアログの可視化
public static void main(String args[]){ ・・・ }
}
§4.デジタルアルバムの作成
ー1日目の課題ー
•
仕様
1.
「ファイル」メニューの他、データ種
ごとに画像用のメニューを持つ。
画像用メニューにはデータ種を表
すタイトルを表示させる。
画像用メニューの項目の選択に応
じて画面中央にデータを表示させ
る。
「ファイル」メニューの「プログラム
の終了」項目及びウインドウの「閉
じる」ボタンにはプログラムを正常
終了させる機能を持たせる。
2.
3.
4.
サンプルプログラムDigitalAlbum.java(1/3)
public void paint(Graphics g)
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image =toolkit.getImage( "flower.jpg" );
g.drawImage( image, 60, 40, this);
}
変更
ファイル名を変更し
た上で再描画
(repaint())
イベントリスナー・クラス
public void actionPerformed(ActionEvent evt)
{
String MenuName = evt.getActionCommand();
if( MenuName.equals("プログラムの終了") )
{
System.exit(0); }
else if( MenuName.equals("お花畑") )
{
;repaint();
}
else if( MenuName.equals("海ホタルから横浜を眺める") )
{
;repaint();
}
else if( MenuName.equals("菜の花") )
分岐処理
{
;repaint();
}
}
サンプルプログラムDigitalAlbum.java(2/3)
class DigitalAlbum extends Frame implements ActionListener{
int PictureNo = 0;
String FileName [] = new String[ 5 ];
public DigitalAlbum( )
{ ・・・
コンストラクタの中で
getFileName();
・・・
getFileNameメソッドを実行
}
private void getFileName(){
FileName[0] = "flowerbet.jpg";
FileName[1] = "yokohama.jpg";
FileName[2] = "flower.jpg";}
public void paint( Graphics g )
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image =toolkit.getImage( FileName[PictureNo] );
g.drawImage( image, 30, 60, this );
}
サンプルプログラムDigitalAlbum.java(3/3)
class DigitalAlbum extends Frame implements ActionListener{
int PictureNo = 0;
変数PicutreNoはメンバ変
String FileName [] = new String[ 5 ];
数なのでどのメソッドからも
参照可能
public void paint( Graphics g )
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image =toolkit.getImage( FileName[PictureNo] );
g.drawImage( image, 30, 60, this );
}
public void actionPerformed(ActionEvent evt){
String MenuName = evt.getActionCommand();
if( MenuName.equals("プログラムの終了") )
{
System.exit(0); }
else if( MenuName.equals("お花畑") )
{PictureNo = 0;repaint();}
else if( MenuName.equals("海ホタルから横浜を眺める") )
{PictureNo = 1;repaint();}
else if( MenuName.equals("菜の花") )
{PictureNo = 2;repaint();}
}