GO BACK

初心者のためのJava教室 その8

「その他のGUI部品」

■チェックボックスとラジオボタン

 とりあえずボタンとラベルだけでAWTの部品配置とイベント処理の基本だけ説明しましたが、もちろんAWTに用意されている部品はこれだけではありません。けっこうたくさんあるのです。そこで、割と使いそうなものの中から、いくつか基本的な使い方を紹介していくことにしましょう。

 まずは「ラジオボタン」と「チェックボックス」からです。どちらもMacやWindowsではお馴染みのものですね。マウスでクリックしてチェックをON/OFFしたり、いくつかある項目から1つを選んだりするのに用いるものです。では、これらを使った簡単なサンプルを作ってみることにしましょう。

import java.awt.*;
import java.awt.event.*;

public class Test6 extends Frame {
Label mylabel;
Checkbox cb1,cb2,cb3;
CheckboxGroup cbg;

public Test6() {
super();
setTitle("Hello");
setSize(300,150);
setLayout(null);

cbg = new CheckboxGroup();
ClickItem il = new ClickItem();

mylabel = new Label("set state!");
mylabel.setBounds(50,25,200,25);
this.add(mylabel);

cb1 = new Checkbox("human");
cb1.setBounds(20,50,150,20);
this.add(cb1);
cb1.addItemListener(il);

cb2 = new Checkbox("male",true,cbg);
cb2.setBounds(20,70,150,20);
this.add(cb2);
cb2. addItemListener(il);

cb3 = new Checkbox("female",false,cbg);
cb3.setBounds(20,90,150,20);
this.add(cb3);
cb3. addItemListener(il);
}

public static void main (String args []) {
new Test6().show();
}

class ClickItem implements ItemListener {

public void itemStateChanged(ItemEvent ev){
String str1,str2;
if (cb1.getState()) {
str1 = "You are Human ";
} else {
str1 = "You are Animal ";
}
if (cb2.getState()) {
str2 = "and male.";
} else {
str2 = "and female.";
}
mylabel.setText(str1 + str2);
}

}

}

 これはチェックボックス1つと切り替え式の2つのラジオボタンを表示したサンプルです。クリックして変更すると、ラベルに表示されたテキストが変わります。

 見ればわかることなんですが、実をいえばチェックボックスとラジオボタンというのは、同じ「Checkbox」っていうクラスのインスタンスなんです。じゃあどこで違いが区別されるのかというと、普通にnewして作っただけならチェックボックスとなり、newするときに「RadiobuttonGroup」っていうもののインスタンスを設定すると、ラジオボタンになるというわけです。

 このRadiobuttonGroupってのは、要するに「ラジオボタンのグループ分けをするためのクラス」と考えればよいでしょう。RadiobuttonGroupのインスタンスを作り、それをいくつかのCheckboxに設定すると、それらが1つのグループとして認識されるようになり、クリックすると常に1つだけがONになるように自動的に行なってくれる、というわけです。

 コードを見るとわかりますが、チェックボックスもラジオボタンも、クリックしてON/OFFするような処理は書く必要はありません。そのあたりは自動的にやってくれます。このへんは便利ですね。

 さて、クリックして設定変更した時の処理へ進みましょう。これは「アイテムリスナー」というもので行ないます。前に、ボタンクリックした時の処理を思い出してみて下さい。アクションリスナーというものを作って、これをボタンに組み込みましたね? チェックボックスやラジオボタンも同じです。アイテムリスナーというクラスを用意して、その中にある「イベントで呼び出されるメソッド」に処理を用意しておき、このクラスのインスタンスを部品に組み込めばいいわけです。

 ここでは「ClickItem」というのが、自作するイベントリスナーのクラスになります。ソースコードを見ると、

ClickItem il = new ClickItem();

こうやって、clickItemというクラスのインスタンスを作ってますね。そして、

cb1.addItemListener(il);

こうやって、部品に「addItemListener」というメソッドでインスタンスを組み込んでいます。まあクラスやメソッドの名前は違いますが、基本的な流れはアクションリスナーの時と同じですね。

 さて、肝心のアイテムリスナーである「ClickItem」クラスですが、これは以下のようになっています。

	class ClickItem implements ItemListener {

public void itemStateChanged(ItemEvent ev){
……ここに処理を書く……
}

}

 わかりますか? アクションリスナーが、implements ActionListenerしてactionPerformedメソッドに処理を書いたのと同様に、アイテムリスナーはimplements ItemListenerしてitemStateChangedメソッドに処理を書きます。細かい部分は違っても、全体の仕組みはだいたい同じことがわかってきますね。

 ここでは、getStateというメソッドで各ボタンのON/OFF状態を調べています。これは真偽値というやつで、ONならばtrue、OFFならばfalseを返します。また反対にON/OFF状態を変更する「setState」というメソッドもあります。例えば「cb1.setState(true)」なんてやれば、cb1をONにできるわけですね。


■チョイスとリスト

 もうちょっと複雑な選択項目に使われるのが「チョイス」と「リスト」です。チョイスってのは、Windowsでいうコンボボックス、Macでいうポップアップメニューみたいなものです。クリックすると項目がずらっと現れ、その中から1つ選ぶ、というものですね。リストは、いわゆる一覧リストです。たくさんの項目が表示されている、あれですね。

 これらもAWTでは用意されています。ただし、チェックボックスなどとちょっと違う点は、「表示する項目を組み込んでいく」という作業が必要なことです。後は、実はそれほど大きな違いはありません。では、これも例をあげておきましょう。

import java.awt.*;
import java.awt.event.*;


public class Test7 extends Frame {
Label mylabel;
Choice c1;
List l1;
ClickItem ci;

public Test7() {
super();
setTitle("Hello");
setSize(300,150);
setLayout(null);
ci = new ClickItem();

mylabel = new Label("set state!");
mylabel.setBounds(50,25,200,25);
this.add(mylabel);

c1 = new Choice();
c1.add("MacOS");
c1.add("Windows");
c1.add("MacOS X");
c1.setBounds(20,70,120,25);
this.add(c1);
c1.addItemListener(ci);

l1 = new List();
l1.add("MacOS");
l1.add("Windows");
l1.add("MacOS X");
l1. setBounds(150,70,120,70);
this.add(l1);
l1.addItemListener(ci);
}

public static void main (String args []) {
new Test7().show();
}

class ClickItem implements ItemListener {

public void itemStateChanged(ItemEvent ev){
if (ev.getSource() == c1) {
int n = c1.getSelectedIndex();
l1.select(n);
}
if (ev.getSource() == l1) {
String str = l1.getSelectedItem();
mylabel.setText(str);
}
}

}

}

 これは、チョイスとリストを1つずつ表示するサンプルです。チョイスを選ぶと、リストの同じ項目が自動的に選ばれます。またリストをクリックして変更すると、選んだ項目名がラベルに表示されます。まあ、ごく単純なものですが、チョイスとリストの基本はわかるかと思います。

 チョイスは「Choice」、リストは「List」というクラスとして用意されています。これらはnewでインスタンスを作った後、こんな作業をしていますね。

c1.add("MacOS");

 このようにaddを使って、表示する項目を組み込んでやらないといけないのです。でないと、何も表示されませんからね。このへんが他の部品とちょっと違うところですね。自分の中にたくさんの項目をもっているわけですから。

 さて、後は実をいうとそう大きな違いはありません。見ると、選択した時のイベント処理はチェックボックスと同じ「アイテムリスナー」ですね。 ということは、itemStateChangedメソッドに処理を用意しておけばいいわけです。

 今回は、2つの部品(チョイスとリスト)のそれぞれで変更した時に異なる処理をさせようと思います。ってことは、itemStateChangedメソッド内で「どれがイベント発生した部品か」をチェックして処理するようにしておきたい、ということです。

 これを行なっているのが、メソッド内にあるif文です。「if (ev.getSource() == c1) { …」なんて感じで書いてあるでしょう?

 このevってのは、パラメータで送られてくるやつですね。メソッドの最初を見ると「itemStateChanged(ItemEvent ev)」ってあるでしょう? つまり、ItemEventのインスタンスをevに入れて渡しますよ、ってことになります。

 イベントリスナーにあるメソッドは、どれもこんな具合に何かのインスタンスをパラメータで渡します。actionPerformedも、そういえば「actionPerformed(ActionEvent ev)」ってなってましたね。これは一体、なんでしょう?

 これが、要するに「イベントの正体」なのだ、と考えるとよいでしょう。今まで「イベント処理」なんて何も考えずにいってましたけど、「イベント」って何です? 宇多田ヒカルのコンサートみたいなやつですか? そんなわけないですよね。

 要するに、「ユーザが操作した部品、マウスの場所、その時のキーボードの状態、操作の種類」といった様々な操作の情報をひとまとめにしてある状況の時にシステムに送ること、それが「イベントの発生」なわけです。「これこれこういう状況の動作が起きたよ」という信号なわけですね。

 そして、その「様々な情報をまとめたもの」が、パラメータに送られてくるActionEventやItemEventのインスタンスなのでした。従って、この中身を調べれば、どんな部品でどういう状況でイベントが発生したのか、知ることができるはずなのです。

 ここでは「ev.getSource()」というものを使っていますね。このgetSource()は、イベント発生源となる部品のインスタンスを示すメソッドです。だから、これがc1ならば、c1(つまりチョイス)でイベントが発生したってことがわかるのですね。――では、やっている処理を見てみましょう。

			if (ev.getSource() == c1) {
int n = c1.getSelectedIndex();
l1.select(n);
}
if (ev.getSource() == l1) {
String str = l1.getSelectedItem();
mylabel.setText(str);
}

 まず、c1(チョイス)の場合は、「c1.getSelectedIndex()」というものの値を取り出し、「l1.select()」というものでその値を設定しています。getSelectedIndex()というのは、現在選択されている項目の番号を返すメソッドで、selectはパラメータで指定した番号の項目を選択するメソッドです。つまり、これでc1と同じ項目をl1で選択させていたわけですね。

 そしてl1(リスト)では、「l1.getSelectedItem()」というのを調べて、その値をラベルに設定しています。このメソッドは、選択されている項目のテキストを取り出すものです。このぐらいのメソッドを覚えておけば、とりあえず「選択された項目を調べたり変更したりする」という基本的な操作はできるようになるでしょう。


■テキスト入力関係の部品

 これらはボタン的な「何かを選んだり設定したりする」という役目のものでしたが、この他に「テキストを入力する」ための部品というのもあります。これも、使うことが多いでしょうから、紹介しておきましょう。それは「TextField」と「TextArea」というものです。2つありますが、前者は1行だけの入力フィールドで、後者はもっとたくさんのテキストを扱う時に利用するためのものです。

import java.awt.*;
import java.awt.event.*;

public class Test8 extends Frame {
TextField tf;
TextArea ta;

public Test8() {
super();
setTitle("Hello");
setSize(300,150);
setLayout(null);

tf = new TextField();
tf.setBounds(20,30,200,18);
this.add(tf);

ta = new TextArea("",5,20,TextArea.SCROLLBARS_VERTICAL_ONLY);
ta. setBounds(20,70,200,60);
this.add(ta);
}

public static void main (String args []) {
new Test8().show();
}

}

 ざっと2つの部品を表示するサンプルを作ってみました。これらは、取りあえずテキストの取りだしや設定などが行えればいいでしょうから、特にイベント処理は用意しませんでした。テキストのやり取りは、ラベルの「getText」「setText」と同じですから、そう難しくはないはずですね。

 まあ、TextFieldは特に説明の要はないでしょう。newして大きさを設定し組み込む、それだけですね。TextAreaの場合は、ちょっとややこしそうです。パラメータが4つもありますね。

new TextArea(表示テキスト, 行数, 列数, スクロールバー設定値)

 まあ、整理するとこんな感じでしょうか。行数と列数は、要するに縦横の幅を文字数単位で指定するってものですね。今回はsetboundsしてしまうのであんまり意味ないんですが、レイアウトマネージャを使ってる時は、ここで設定しておけば、その文字数行数が表示される大きさに調整されるんです。

 最後のスクロールバーの設定値ってのがわからないでしょう。これは「縦横のスクロールバーを表示するのかどうかということです。例えば、サンプルでは縦方向のスクロールバーが表示されていますね。これらは、TextAreaに用意されている定数を使って指定するのが一般的です。

SCROLLBARS_NONE(なし)
SCROLLBARS_VERTICAL_ONLY(縦だけ)
SCROLLBARS_HORIZONTAL_ONLY(横だけ)
SCROLLBARS_BOTH (両方)

 この4つの中のどれかを設定する、と考えて下さい。こうした定数は、「TextArea.SCROLLBARS_VERTICAL_ONLY」というように、クラス名の後に定数名を記述して指定します。

 ――というわけで、主なGUI部品を使ってみました。他にもまだあるのですが、長くなってきたのでこのへんにしておきます。とりあえずこれだけ使えるようになれば、ちょっとしたプログラムを作るには十分だと思いますし、後はこれらを覚えた後で少しずつ調べていけばよいでしょう。実際に動かして、部品の基本的な使い方をマスターしておきましょう。



GO NEXT


GO HOME