<イベントの扱い>
<例8: リスナを使ったイベント駆動>
- GUIを持つプログラムは大抵,イベント駆動型プログラムである.
- イベントとは,ここでは,GUIを操作した際に発生するメッセージだと思って良い.
- イベント駆動プログラムは,イベントが発生したら何かするという処理形式で動く.
例: ボタンを押したらラベルの数値が増える.
等.
ソースコード<例9: 聞き手を複数にするのも簡単>
import java.applet.*; import java.awt.*; import java.awt.event.*; public class ButtonListen extends Applet{ public void init(){ Button b=new Button("Up"); MSLabel ms=new MSLabel(0); b.addMouseListener(ms); this.add(b); ↑ this.add(ms); ボタンbのイベントをラベルmsが聞くように指示 } } class MSLabel extends Label implements MouseListener{ private int; MSLabel(int initn){ n=initn; setText(n+""); } public void mouseClicked(MouseEvent e){ n++; setText(n+""); } public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e){} } ↑ ボタン系のイベントに対応して行う処理を, ラベル(リスナー)内に実装
ソースコード
public class ButtonListen extends Applet{ public void init(){ Button b=new Button("Up"); add(b); for(int i=0; i<5; i++){ MSLabel ms=new MSLabel(i); b.addMouseListener(ms); this.add(ms); } } }
他の部分は前と同じ
<イベントリスナのまとめ>
<例10: ソースが複数の場合は?>
- かなり安直にイベント処理が実装可能.
- マウス以外にもいろいろあり.
- KeyListener
- ActionListener, TextListener …
- 使わないイベント処理メソッドも実装しないといけないので優雅でない.
ソースコード
●複数のソースが同じリスナを登録してもOK public class ButtonUpDown extends Applet{ public void init(){ Button up=new Button("Up"); Button down=new Button("Down"); MSLabel ms=new MSLabel(0); up.addMouseListener(ms); down.addMouseListener(ms); add(up); add(ms); add(down); } } ●どのソースからのイベントかを判断するには,Eventクラス内の情報を利用 class MSLabel extends Label implements MouseListener{ private int n; MSLabel(int initn){ n=initn; setText(n+""); } public void mouseClicked(MouseEvent e){ Button b=(Button)e.getComponent(); if(b.getLabel().equals("Up")) n++; else n--; setText(n+""); }
<イベントクラスのまとめ>
- イベント処理メソッドの引数にあるEvent系のオブジェクトから,イベントソースに関する情報が得られる.
<アダプタによるイベント処理>
<例11: ボタン・ラベル再び>
- リスナインタフェースを空実装してある具象クラス群のこと.
- アダプタの使い方.
- アダプタのサブクラスを作る.
- 実際の聞き手である部品をそのクラスに与える.
- イベントに応じて実際の聞き手部品のメソッドを呼ぶように,イベント処理メソッドを再定義.
ソースコード ※場所の都合,一部省略.
public class ButtonAdapt extends Applet{ public void init(){ Button b=new Button("Up"); add(b); for(int i=0; i<5; i++){ Label ms=new Label(); b.addMouseListener(new LMouseAdapter(ms, i)); this.add(ms); } } } class LMouseAdapter extends MouseAdapter{ private Label lbl; private int counter; LMouseAdapter(Label initlbl, int c){ lbl=initlbl; counter=c; lbl.setText(counter+""); } public void mousePressed(MouseEvent e){ counter++; lbl.setText(counter+""); } ↑ } 実際の聞き手lblの変更
<アダプタ作りのTIPS>
<例12: インナークラス>
- リスナ・インタフェースを実装するよりかなりマシになった.
- さらに,便利に書くテクニックとして,
- インナー・クラス
- 無名インナークラス
- 無論,アダプタ以外のJava記述にも便利に使える.
ソースコード<例13: 無名インナークラス>
import java.applet.*; import java.awt.*; import java.awt.event.*; public class ButtonInner extends Applet{ public void init(){ Button b=new Button("Up"); add(b); for(int i=0; i<5; i++){ Label ms=new Label(); b.addMouseListener(new LMouseAdapter(ms, i)); this.add(ms); } } class LMouseAdapter extends MouseAdapter{ private Label lbl; private int counter; LMouseAdapter(Label initlbl, int c){ lbl=initlbl; counter=c; lbl.setText(counter+""); } public void mousePressed(MouseEvent e){ counter++; lbl.setText(counter+""); } } }
ソースコード
名前の参照を以後行わないクラスは以下のようにインスタンスを作れる. 内部変数,初期化等があるとちょっと厄介. インタフェースも使える.
import java.applet.*; import java.awt.*; import java.awt.event.*; public class ButtonAnony extends Applet{ int i; Label ms; public void init(){ Button b=new Button("Up"); add(b); for(i=0; i<5; i++){ ms=new Label(); ms.setText(i+""); b.addMouseListener( new MouseAdapter(){ private Label lbl=ms; private int counter=i; public void mousePressed(MouseEvent e){ counter++; lbl.setText(counter+""); } } ); this.add(ms); } } }
<Paintする場合の注意点>
- Paintメソッド(Containerで定義)を使い,部品に直接描画できた.
- イベントに応じて,ペイント描画を変更するにはちょっと注意が必要.
- 具体的には再描画させないといけない.
- repaint
<コンテナ内の部品・レイアウトの変化について>
- あるイベントによって,コンテナ内の部品数,レイアウト等が変化した場合.
- validate が必要.
実習用の各種ファイルはここから参照&ダウンロード!
2003年10月22日 6:23 更新