[目次] [前回] [次回] [重要語索引]

第9週: イベント

9. 1 イベント
9. 2 イベントリスナーの登録
9. 3 練習問題
9. 4 マウスイベント
9. 5 練習問題
9. 6 宿題
9. 7 おまけ

9.1 イベント

SfcTemplate1.java では、マウスでボタンをクリックした時に、sfcProcess メソッドが呼び出されて、その中に書いておいた処理が実行されます。これは、具体的にはどこで呼び出しているのでしょうか?

メソッドの中では、あらかじめ決められた順序で実行が進んでいきますが、人間がマウスをいつクリックするかは予想がつきません。ですから、あらかじめメソッド呼び出しを書いておくことはできません。

このように、いつ起こるか分からないことを扱うために、AWT ではイベント(event)というものを使います。イベントには発生源となるオブジェクト(イベントソース)と、イベントが起きるのを待っているオブジェクト(イベントリスナー)があります。

例えば、ボタンをクリックした場合、そのボタンを発生源とするイベントが発生します。イベントにはいろいろな種類がありますが、ボタンの場合はActionEvent クラスのインスタンスで表されるイベントと決まっています。

9.2 イベントリスナーの登録

発生したイベントはイベントリスナーに伝えられますが、どのオブジェクトがイベントリスナーであるかは、あらかじめ登録しておかなければなりません。また、どんなオブジェクトでもイベントリスナーとして登録できるわけではありません。ですから、イベントを扱うプログラムは次の点に注意する必要があります。

  1. イベントリスナーになるための条件を満たすクラスがあること。
  2. そのクラスのインスタンスを少なくとも一つ作ること。
  3. そのインスタンスを、イベントの発生源に登録すること。

イベントリスナーになるための条件

ボタンから発生した ActionEvent を受け取るためには、次の二つの条件を満たすクラスのインスタンスである必要があります。SfcTemplate1.java の場合は、SfcTemplate1 というクラス自身がこの条件を満たしています。

注意: ActionEvent クラスは、AWT に含まれるクラスですが、クラス宣言の置場所は java.awt のすぐ下ではなく、java.awt.event の下なので、import 文は別に書く必要があります。
    import java.awt.event.*;

イベントリスナーのインスタンスの作成

SfcTemplate1.java の場合は、appletviewer またはウェブブラウザが、起動した時に自動的にインスタンスを作るので、自分でインスタンスを作る必要はありません。

イベントリスナーの登録

イベントの発生源であるオブジェクト(この場合は変数 b1 が記憶している Button クラスのインスタンス)に、addActionListener メソッドを使って、イベントリスナーを登録します。
28
	b1.addActionListener(this);

引数はイベントリスナーになるオブジェクトです。この場合は、このメソッドを実行しているインスタンス自身なので、自分自身を指す this という特別な変数を使います。

イベントの通知

人間がマウスで画面上のボタンをクリックすると、Button クラスのインスタンスは、「ボタンがクリックされた」というイベント(ActionEvent クラスのインスタンス)を作成し、登録されているイベントリスナーの actionPerformed メソッドを呼び出します。

event

SfcTemplate1 クラスでは、actionPerformed メソッドの中身は sfcProcess メソッドを呼び出すだけです。ActionEvent クラスのインスタンスが仮引数 e に代入されますが、これは全く使っていません。

9.3 練習問題

前に作った MovingBall.java は、ボタンを押しても何も起こりません。これではおもしろくないので、ボタンを押すとボールの色が変わるようにしましょう。現在の色が青なら赤に、赤なら緑に、緑なら青に変えることにします。
  1. MovingBall クラスは、ボタンから発生するイベントを受け取るイベントリスナーの条件を満たしているか、確認しなさい。
  2. MovingBall クラスのインスタンスは、自分をイベントリスナーとして登録しているか、確認しなさい。
  3. actionPerformed メソッドの中には何を書けばいいでしょうか。
  4. changeColorBall クラスのインスタンスが実行すべきメソッドです。
    オブジェクトの比較には、数値の比較と同じ == を使う方法と、equals メソッドを使う方法の二つがあります。ここでは、この二つの差について説明しませんが、== を使うにはオブジェクトの参照の仕組みについて理解している必要があるので、equals メソッドを使う方が良いでしょう。例えば、cColor.red が等しいかどうか比較するには、
        c.equals(Color.red)
    
    または
        Color.red.equals(c)
    
    とします。

実行例

9.4 マウスイベント

イベントの種類が違うと、対応するイベントリスナーや、呼び出されるメソッドの名前が違います。次は、キャンバスでマウスをクリックした時のイベントについて見てみましょう。

SfcTemplate1.java にはキャンバスがありませんから、SfcTemplate3.java で説明します。プログラムの基本的な構造はボタンの時と同じです。

  1. イベントリスナーになるための条件を満たすクラスがあること。
  2. そのクラスのインスタンスを少なくとも一つ作ること。
  3. そのインスタンスを、イベントの発生源に登録すること。

イベントリスナーになるための条件

implements の後に書くイベントリスナーの種類はMouseListener、宣言するメソッドは mouseClicked,mouseEntered, mouseExited, mousePressed, mouseReleased の五つです。引数は、どれも MouseEvent クラスのインスタンスです。
 9
10
public class SfcTemplate3 extends Applet
    implements ActionListener, MouseListener, MouseMotionListener, Runnable {
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    public void mouseClicked(MouseEvent e) {
	// 描画領域でマウスボタンをクリックしたときの処理
    }

    public void mouseEntered(MouseEvent e) {
	// 描画領域にマウスカーソルが入ったときの処理
    }

    public void mouseExited(MouseEvent e) {
	// 描画領域からマウスカーソルが出たときの処理
    }

    public void mousePressed(MouseEvent e) {
	// 描画領域でマウスボタンを押したときの処理
    }

    public void mouseReleased(MouseEvent e) {
	// 描画領域でマウスボタンを離したときの処理
    }

イベントリスナーのインスタンスの作成

SfcTemplate3.java の場合は、appletviewer またはウェブブラウザが、起動した時に自動的にインスタンスを作るので、自分でインスタンスを作る必要はありません。

イベントリスナーの登録

登録するためのメソッドは addMouseListener です。登録する相手は、変数 c1 が記憶している Canvas クラスのインスタンスです。
34
	c1.addMouseListener(this);

イベントの通知

マウスの動きによって、プログラム中のコメントに書いてあるように、五つのメソッドのどれかが呼び出されます。

注意: マウスを動かした時にもイベントを通知することができますが、それはMouseMotionListener という別のイベントリスナーになります。詳しくはこちらを見てください。

9.5 練習問題

MovingBall.java を変更し、キャンバス上でマウスをクリックすると、その位置にすべてのボールが移動するようにしなさい。
  1. まず、Ball クラスに、座標を変更するメソッドを追加しましょう。引数は X 座標と Y 座標の二つで、その値をインスタンス変数の x,y に代入します。このメソッドの名前を changePosition としましょう。
  2. mouseClicked メソッドの中で、各インスタンスのchangePostion メソッドを呼び出せばいいのですが、その時に指定する引数として、マウスをクリックした点の座標が必要です。
    • マウスをクリックした点の座標は、イベントが発生したときに作られた MouseEvent クラスのインスタンスがデータとして持っています。
    • このインスタンスは、mouseClicked メソッドが呼び出されたときに、仮引数 e に代入されます。
    • X 座標を得るには、変数 e が記憶しているMouseEvent クラスのインスタンスの getX メソッドを呼び出します。
          e.getX()
      
      すると、返り値として X 座標の値が得られます。Y 座標は同様に
          e.getY()
      
      です。

9.6 宿題

MovingBall.java を変更し、キャンバス下端に適当な大きさの長方形を描き、その位置はマウスカーソルの X 座標に連動するようにしなさい。

注意:ラベルやボタンの文字を大きくすると、その分キャンバスの大きさが小さくなります。ボールが Y 座標 300 の位置で跳ね返るのがボタンに隠れてしまう場合は、マウスでウィンドウを広げるか、MovingBall.html 内の height の指定を大きくしてください。

  1. 長方形を描くためのクラス Racket を作ります。このクラスには次のものが必要です。
  2. ボールと同じようにインスタンスを作り、0.2秒間隔で drawメソッドを呼び出すようにします。
  3. キャンバス内でマウスを動かすと、mouseMoved メソッドが呼び出されます。そこで、Racket クラスのインスタンスの changePosition メソッドを呼び出すようにします。

実行例

9.7 おまけ

MovingBall.java を変更し、キャンバス内でマウスをクリックすると、その位置に新しいボールができて動き始めるようにしなさい。


[目次] [前回] [次回] [重要語索引]

慶應義塾大学の授業以外での無断利用、複製はご遠慮下さい。
Copyright (c) 2000 慶應義塾大学