| 7. イベント処理 |
このとき、リスナではイベント処理用のメソッドとしてあらかじめ決められているメソッドを実行します。ActionEvent の場合には actionPerformed( ) というメソッドを実行すると決められています。
ですから、ActionEvent を処理するリスナのクラスは、
Java のイベント処理のしかたについて説明します。
(1) ボタンを押しても動かない
前回、ボタンを使ってレイアウトを3種類見てきました。これらのボタンを押しても何も起こりませんでしたが、これはイベント処理をしていないからです。
Java ではイベント処理を行う場合、 DelegationEventModel というモデルを使います。このモデルを使っていく場合、2つの言葉が出てきます。1つはイベントソース、もう1つはリスナです。
たとえば、「ボタンを押すとメッセージを表示する」という処理を書きたい場合、ボタンを押すと「ボタンが押された」というイベントが発生します。そして、このイベント発生を受けて、メッセージを表示する処理が動きだします。
このとき、イベントを発生させることになったコンポーネント、つまりボタンがイベントソースとなります。そして、メッセージを表示する処理を行うものがリスナになります。
(2) イベントが処理されるまで
イベントソースはこの後に出てくる Button や List のようなコンポーネントのクラスが担当します。イベント処理はリスナが担当します。この2つは基本的には別々の物なので、「このイベントソースでイベントが発生したら、 このリスナで処理をする」という関連付けをしてやらなければなりません。この関連づけのことをリスナの登録といいます。Java ではイベントソースにリスナを登録することで、関連づけを行います。
先ほどのボタンを押すという例に戻ってイベント処理の流れを追っていきます。 Java ではボタンを押したとき、ActionEvent という名前のイベントが発生します。 ActionEvent はイベント名ですが、これは java.awt.event パッケージに定義されているクラス名でもあります。
Java ではイベントが発生すると、イベントオブジェクトというものが生成されます。ActionEvent が発生すると、ActionEvent オブジェクトが生成されます。このイベントオブジェクトにはどこでどんなイベントが発生したか、というような情報が入っています。
イベントが発生すると、ボタンに登録されているリスナに「イベントが発生しましたよ」 という通知が行きます。このとき、同時にイベントオブジェクトもリスナに渡します。通知を受けたリスナは実際にその後のイベント処理(メッセージの表示など)を行います。
イベントソースやイベントは自分で作ることもできます。
(3) リスナの作り方と登録
イベントを処理するリスナには作り方にいくつかのルールがあります。1つは、イベントを処理するためのメソッドが決まっているということ。もう1つは、イベント処理用のメソッドはインタフェースに定義されているので、これを実装したクラスを作るということです。
ActionEvent の場合、このイベントを処理するためのメソッドは、 actionPerformed(ActionEvent e) という名前のメソッド、と決められています。そして、このメソッドは自分で勝手に作るのではなく、 ActionListener というインタフェースに定義されている actionPerformed( ) をオーバーライドする、というように決まっています。
// MyHandler.java
import java.awt.event.*;
class MyHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("ボタンがおされたよ");
}
}
というように書いていきます。 ActionEvent クラス、ActionListener インタフェースが java.awt.event パッケージにあるのでインポートして使います。
これでリスナはできあがったので、次にボタンとこのリスナの関連づけ、リスナの登録を行います。 ActionEvent を処理するリスナを登録するメソッドは、 addActionListener(ActionListener l) という形式のメソッドです。この登録用のメソッドは各コンポーネントのクラスが持っています。ボタンの場合は Button クラスに定義されています。
addActionListner の引数の型は ActionListener 型になっていますが、 これは Actionlistener インタフェースを実装したクラスのオブジェクトが指定できるという意味です。
次の例では1つのソースファイル内に2つのクラスを定義していますが、別のソースファイルに定義しても構いません。
ActionTest.java
// ActionTest.java
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class ActionTest extends Applet {
public void init() {
// ボタン作成・追加
Button b = new Button("OK");
add(b);
// リスナ登録 (ボタンにリスナを登録する)
MyHandler handle = new MyHandler();
b.addActionListener(handle);
}
}
// リスナ
class MyHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("ボタンがおされたよ");
}
}
ActionTest.html
<APPLET CODE=ActionTest.class width=200 height=100>
</APPLET>
実行例 (画像をクリックすると実際のActionTest.html のアプレットが起動します)
C:\java_test>appletviewer ActionTest.html ボタンがおされたよ |
| (4) その他のイベントの種類 |
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class MouseEventTest extends Applet implements MouseListener {
public void init() {
// リスナ登録
// このクラス(Applet)がイベントソースでリスナになる
addMouseListener(this);
}
// MouseListenerに定義されている5つのメソッド
public void mouseClicked(MouseEvent e) {
System.out.println("クリックされました");
}
// メソッドがイベント処理に必要が無いときも、
// インタフェース内のメソッドは
// すべてオーバーライドする必要があります
// マウスボタンが押された
public void mousePressed(MouseEvent e) {
}
// マウスボタンが放された
public void mouseReleased(MouseEvent e) {
}
// イベントソース(アプレット)にマウスポインタが入った
public void mouseEntered(MouseEvent e) {
}
// イベントソース(アプレット)からマウスポインタが出た
public void mouseExited(MouseEvent e) {
}
}
|
<APPLET CODE=MouseEventTest.class width=250 height=200> </APPLET> |
| (5) イベントオブジェクトの使いみち |
たとえば、ボタンが2つあったとき、この2つのボタンに同じリスナを登録すると、どちらのボタンを押しても同じ actionPerformed が実行されます。このとき、この2つのボタンを判別したい場合はどうしたらよいでしょう。
ここで先に挙げた、getSource( ) や getActionCommand( ) を使います。getSource( ) では押したボタンのオブジェクトが戻り値としてそのまま返ってきます。ただし、型は Object です。また、getActionCommand( ) は、ボタンの場合はラベルが返ってきます。
これらの情報を利用して、イベントソースを判断したり、詳細情報を得たりします。
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class EObjectTest extends Applet implements ActionListener {
Button b1,b2;
public void init() {
// ボタン作成・追加
b1 = new Button("One");
b2 = new Button("Two");
add(b1);
add(b2);
// リスナ登録
b1.addActionListener(this);
b2.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
// getSource() でイベントソースのオブジェクトを獲得し
// Button クラスにキャストする
Button b = (Button)e.getSource();
// getActionCommand() でボタンのラベルを獲得する
System.out.println("Label : "+e.getActionCommand());
// getSource() で獲得したオブジェクトとはじめに作った
// ボタンのオブジェクトが一致するか調べる
if (b==b1) {
System.out.println("Oneのボタン");
}
if (b==b2) {
System.out.println("Twoのボタン");
}
// ボタンのラベルで比較する場合には
// String クラスの文字列比較用のメソッド equals() を使って
// if ( e.getActionCommand().equals("One") ) とします
}
}
|
<APPLET CODE=EObjectTest.class width=250 height=100> </APPLET> |
C:\java_test>appletviewer EObjectTest.html Label : One Oneのボタン Label : Two Twoのボタン |