ActionListener組み込みのアレンジ
なぜエラーになったのか? それは、ActionAdapterのクラスからは、Sampleクラス内のフィールドが「見えない」からです。JLabelやJTextFieldといったコンポーネントは、Sampleクラス内にフィールドとして用意されています。これらは、ActionAdapterクラスからは、そのままでは利用できないのです。なぜなら、ActionAdapterはSampleとは別のクラスなのですから。
これを利用するためには、実行中のSampleインスタンスを何らかの方法で取得し、その中のフィールドを利用する必要があります。けれど、一見すると何の関係もないActionAdapterからどうやって実行中のSampleインスタンスを取り出せばいいのか? 途方にくれてしまいますね。
この問題を解決するにはどうすればよいのか? 結局、「ActionAdapterが別のクラスである」からこういう問題が起こるのです。Sampleクラス自身にActionListenerの機能を組み込んでしまえば、このような問題も起こりません。
import java.awt.*;
import java.awt.event.*;
public class Sample extends Frame implements ActionListener {
Label label1;
TextField field1;
Button button1;
public static void main(String[] args){
new Sample();
}
public Sample(){
this.setLayout(null);
this.setSize(200,140);
label1 = new Label("こんにちは!");
field1 = new TextField();
button1 = new Button("Click");
label1.setBounds(20,40,160,20);
field1.setBounds(20,70,160,20);
button1.setBounds(50,100,100,20);
button1.addActionListener(this);
this.add(label1);
this.add(field1);
this.add(button1);
this.setVisible(true);
}
public void actionPerformed(ActionEvent ev){
String s = field1.getText();
label1.setText(s + "と書きました。");
}
}
ボタンをクリックすると、入力したテキストを調べてテキストを表示します。 |
これがその例です。Sampleの部分にimplements ActionListenrがつけられていますね。そしてアクションリスナーの組み込みでは、button1.addActionListener(this);というようにthisを指定しています。thisは、インスタンス自身を示すものでしたね。こうすることで、自分自身をリスナーとして登録していたわけです。
この他に「アクションリスナーのクラスを、Sampleクラスの中にクラスごと組み込んでしまう」といった方法もあります。これは、以下のような形で記述します。
import java.awt.*;
import java.awt.event.*;
public class Sample extends Frame {
Label label1;
TextField field1;
Button button1;
public static void main(String[] args){
new Sample();
}
public Sample(){
this.setLayout(null);
this.setSize(200,140);
label1 = new Label("こんにちは!");
field1 = new TextField();
button1 = new Button("Click");
label1.setBounds(20,40,160,20);
field1.setBounds(20,70,160,20);
button1.setBounds(50,100,100,20);
button1.addActionListener(new ActionAdapter());
this.add(label1);
this.add(field1);
this.add(button1);
this.setVisible(true);
}
class ActionAdapter implements ActionListener {
public void actionPerformed(ActionEvent ev){
String s = field1.getText();
label1.setText(s + "と書きました。");
}
}
}
よく見ると、ActionAdapterクラスの定義そのものがSampleクラスの中に組み込まれてしまっていることがわかるでしょう。このように「クラスの中に定義されているクラス」のことを「内部クラス(インナークラス)」と呼びます。内部クラスは、Sampleクラスの中にクラスの要素のひとつとして書かれていますから、Sampleクラス内のフィールドやメソッドを自由に利用することができます。
アクションリスナーの組み込み方はいろいろとありますが、ここであげた「自分自身にimplementsしてしまう方法」と「内部クラスとして持たせる方法」がもっとも基本となるものといってよいでしょう。この2つの方法を使えるようになれば、イベントリスナーの基本はマスターできます。ちょっとわかりにくいかも知れませんが、実際に何度かソースコードを自分で書いてみれば、自然と意味がわかってくるものですよ!
バックナンバー
はじめてのJava(1)「Javaを手に入れよう」はじめてのJava(2)「環境変数をマスターする」
はじめてのJava(3)「Javaのプログラムを動かそう」
はじめてのJava(4)「mainメソッドを使おう」
はじめてのJava(5)「制御文を使おう」
はじめてのJava(6)「クラスとインスタンスをマスターしよう」
はじめてのJava(7)「AWTのコンポーネントを使おう」