画面にボタンなどの部品を配置する方法や、クリックしたときにどのように処理を行わせるかがわかれば、GUIプログラミングは楽しくなります。
【1】sample200 フォルダをフォルダごとコピーして、sample204 フォルダを作ります。

【2】今回は以下のようなファイル構成になりますので、コピーした余計なものは削除してください。

【3】PrefTest.java を以下のように変更します。
*「\」はWindowsではエンマークのことです。
保存先 C:\java\sample204
ファイル名 PrefTest.java
import java.awt.*;
import java.awt.event.*;
class PrefFrame extends Frame implements ActionListener {
Label lb1;
TextArea txtar1;
Button btn1, btn2, btn3;
public PrefFrame(String title) {
//フレームのタイトル
setTitle(title);
//ウィンドウを閉じる時
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//ラベル
lb1 = new Label("ボタンをクリックしてください。", Label.CENTER);
add(lb1, BorderLayout.NORTH);
//テキストエリア
txtar1 = new TextArea();
add(txtar1, BorderLayout.CENTER);
//パネル
Panel pn1 = new Panel();
pn1.setLayout(new GridLayout(1, 3));
//ボタンの設定とパネルへ追加
btn1 = new Button("表示");
btn1.addActionListener(this);
pn1.add(btn1);
btn2 = new Button("クリア");
btn2.addActionListener(this);
pn1.add(btn2);
btn3 = new Button("終了");
btn3.addActionListener(this);
pn1.add(btn3);
//パネルを追加
add(pn1, BorderLayout.SOUTH);
}
public void actionPerformed (ActionEvent e) {
if (e.getSource() == btn1) {
prefDisplay();
}else if (e.getSource() == btn2) {
txtar1.setText("");
}else {
System.exit(0);
}
}
private void prefDisplay () {
StringBuffer temp = new StringBuffer();
temp.append("1" + "\t");
temp.append("北海道" + "\n");
temp.append("2" + "\t");
temp.append("青森県" + "\n");
temp.append("3" + "\t");
temp.append("岩手県" + "\n");
temp.append("4" + "\t");
temp.append("宮城県" + "\n");
temp.append("5" + "\t");
temp.append("秋田県" + "\n");
txtar1.setText(temp.toString());
}
}
public class PrefTest {
public static void main(String args[]) {
PrefFrame frm = new PrefFrame("都道府県マスター");
//フレームの設定
frm.setLocation(300, 200);
frm.setSize(250, 350);
frm.setBackground(Color.LIGHT_GRAY);
frm.setVisible(true);
}
}
【4】コマンドプロンプトを起動して、カレントディレクトリを sample204 に切り替えます。

【5】javac PrefTest.java と入力し、コンパイルします。

【6】java PrefTest と入力し、プログラムを実行します。

【7】ウィンドウが表示されました。ラベル、テキストエリア、ボタンが表示されています。

【8】「表示」ボタンをクリックします。

【9】テキストエリアに都道府県が表示されました。表示は一部都道府県だけです。

【10】「クリア」ボタンをクリックします。

【11】テキストエリアがクリアされました。

【12】「終了」ボタンをクリックします。

【13】ウィンドウが閉じ、コマンドプロンプトが命令を受け付ける状態になりました。

【解説】
(1)ボタン、ラベル、テキストフィールド、テキストエリア、スクロールバーなどのGUIオブジェクトのことをコンポーネントと言います。
(2)コンポーネントは、クラス内の各メソッドから参照できるように、メソッドの外で定義しています。またテスト用のクラスから参照することもあるので、アクセス修飾子は「指定なし」にしました。
Label lb1;
TextArea txtar1;
Button btn1, btn2, btn3;
(3)コンポーネントを格納するものをコンテナと言います。コンテナは他のコンテナも格納できます。コンテナにはコンポーネントをどのように配置するかを制御する、レイアウトマネージャがあります。レイアウトマネージャを使うときは、setLayout()メソッドでどのレイアウトを使うか指定します。
主なレイアウト
FlowLayout、GridLayout、BorderLayout、GridBagLayout、CardLayout
他にもレイアウトには様々なものがあるので、API仕様で一度確認してみてください。
java.awt → LayoutManagerとLayoutManager2

(3)Frameクラスのデフォルト(初期設定)ではBorderLayoutになっています。

(4)ラベルを作成し行揃えは中央で、BorderLayoutの北に配置しています。
lb1 = new Label("ボタンをクリックしてください。", Label.CENTER);
add(lb1, BorderLayout.NORTH);
(5)テキストエリアを作成し、BorderLayoutの中央に配置しています。
txtar1 = new TextArea();
add(txtar1, BorderLayout.CENTER);
*テキストエリアは複数行テキストを表示したり入力できます。
(6)BorderLayoutは1つの領域に1つのコンポーネントしか配置できないので、複数のコンポーネントを扱うときは、少し工夫が必要です。図にすると以下のようなイメージです。
Panel(パネル)を作りPanelにボタンを追加して、PanelをBorderLayoutの南に配置します。

BorderLayoutに配置したイメージ

今回は、東西は使わないので最終的に以下のようなイメージになります。

それではプログラムではどのように書けばいいのか見てみましょう。
(7)まずPanelクラスのインスタンスを生成します。Panelはコンポーネントを格納できる単純なコンテナです。PanelクラスはデフォルトではFlowLayoutになっているので、GridLayoutに変更し、1行3列にしています。GridLayoutはコンポーネントを縦横の格子に配置します。
Panel pn1 = new Panel();
pn1.setLayout(new GridLayout(1, 3));
最初からレイアウトマネージャを指定してインスタンスを生成することもできます。
Panel pn1 = new Panel(new GridLayout(1, 3));
(8)次にボタンを作り、イベントリスナーのウィンドウ(this)をイベントソースのボタンに登録して、パネルに追加しています。
btn1 = new Button("表示");
btn1.addActionListener(this);
pn1.add(btn1);
*ウィンドウはFrameクラスを継承し、インターフェイスを実装しています。
(9)PanelをBorderLayoutの南に配置しています。
add(pn1, BorderLayout.SOUTH);
(10)イベントとは
マウスやキーボードなどの操作、ボタンのクリックなどによって発生した状態の変化を「イベント」(出来事)と言います。イベントのきっかけになったボタンなどを「イベントソース」と言います。
各イベントに対応した処理を行うことを「イベント処理」といいます。またイベントを検出できるように監視する役割を「イベントリスナー」といいます。
イベントリスナーはイベントリスナーインターフェイスを実装し、イベントに対応したイベントハンドラをオーバーライドしたクラスです。
*重要な点ですが、イベントリスナーはウィンドウの時もあればラベルなどのコンポーネントの時もあります。イベントリスナーとしての機能を実装していればいいわけです。
イベントが発生するとイベントオブジェクトが発生するので、イベントハンドラで受け取って、あらかじめプログラムした処理を行います。
イベントの種類によって、イベントリスナーインターフェイス、イベントリスナー登録メソッド、イベントオブジェクト、オーバーライドしなければならないイベントハンドラが異なります。以下は今回の例です。
・イベントリスナーインターフェイスを実装
class PrefFrame extends Frame implements ActionListener {
ActionListenerがインターフェイスです。
・イベントリスナー登録メソッド
btn1.addActionListener(this);
btn1はイベントソース、addActionListener()はButtonクラスのメソッド、thisはイベントリスナーであるウィンドウ(オブジェクト自身)です。
・イベントハンドラ
actionPerformed (ActionEvent e)
イベントに対応したメソッドをオーバーライドしている部分です。メソッドの引数 e にはイベント情報が渡されます。
*インターフェイスを実装するには、インターフェイスのすべての抽象メソッドをオーバーライドしなければなりません。今回使ったActionListenerの抽象メソッドはactionPerformed()メソッド1つだけなので楽です。
(11)イベントが発生すると、イベントハンドラのactionPerformed()メソッドが呼び出されます。このメソッドでは、どのボタンが押されたかによって処理を分岐しています。
・btn1ボタンが押されたときは、prefDisplay()メソッドを呼び出す。
・btn2ボタンが押されたときは、テキストエリアをクリアする。
・他のボタンが押されたときはシステムを終了する。
public void actionPerformed (ActionEvent e) {
if (e.getSource() == btn1) {
prefDisplay();
}else if (e.getSource() == btn2) {
txtar1.setText("");
}else {
System.exit(0);
}
}
(12)prefDisplay()メソッドについて
このメソッドは同じクラス内からしか利用しないので、アクセス修飾子を「private 」にしています。
内容が更新される文字列を扱うときは、StringBufferクラスを使います。Stringクラスは固定文字列であり、文字を追加する度にインスタンスを作り直すため、効率が低下するからです。
StringBufferクラスのappend()メソッドで文字列を追加していき、toString()メソッドで文字列を得ています。それをテキストエリアに表示しています。データの表示にテキストエリアを使っているのは、最適ということではなく一番簡単な方法だからです。
StringBuffer temp = new StringBuffer();
temp.append("1" + "\t");
temp.append("北海道" + "\n");
temp.append("2" + "\t");
temp.append("青森県" + "\n");
temp.append("3" + "\t");
temp.append("岩手県" + "\n");
temp.append("4" + "\t");
temp.append("宮城県" + "\n");
temp.append("5" + "\t");
temp.append("秋田県" + "\n");
txtar1.setText(temp.toString());
*「\t」はタブで、「\n」は改行を表しています。
今回は内容が少し難しかったので、データベースからデータを取得する機能はあえて外しました。この機能は次回に付けることにします。
前にやったCUIプログラミングでは「レイアウト」と「イベント処理」が無いので、プログラムがシンプルで楽だったことがわかったと思います。