ホーム
AWT
Java には、AWT(Abstract Window Toolkit)と呼ばれる GUI アプリケーションを作成するためのクラス群が揃っています。このように何かするために揃えられたクラス群のことを Java ではパッケージ(package)と呼びます。他のプログラミング言語ではライブラリ(library)と呼ぶことが多いみたいです。
GUI の代表的なものはウィンドウでしょう。Java ではウィンドウのことをフレーム(frame)とも呼びます。ウィンドウはアプリケーションの土台となり、いろいろな GUI 部品を配置できる特別なものですが、ウィンドウ自身も 1 つの GUI 部品であることに変わりはありません。
なお、Java では、GUI 部品のことをコンポーネント(component)と呼びます。ウィンドウもコンポーネントの 1 つになります。
次のコードは、ウィンドウを表示するだけのアプリケーションのコードです。
Java はファイル名とクラス名を同じにしなければならないので、このコーナーでは、ファイル名は Hello.java、クラス名は Hello と決めています。
Hello.java
import java.awt.*;
class Hello {
public static void main(String[] args) {
Frame frame = new Frame("Frame");
frame.setSize(200, 100);
frame.setVisible(true);
}
}
コード説明
import java.awt.*;
AWT を使うには java.awt.*; というパッケージを読み込まなければなりません。
class Hello {
Java では、すべてをクラス(class)単位で処理します。
public static void main(String[] args) {
Java の main はこのように書く決まりになっています。なお Java では、クラスに所属している関数のことをメソッド(method)と呼び、クラスに所属している変数のことをフィールド(field)と呼びます。したがって main は main メソッドと呼ぶことになります。
Frame frame = new Frame("Frame");
Frame は awt パッケージに入っているウィンドウに関するクラスです。Java ではクラスのインスタンスを作るには new メソッドを使います。おそらく Frame クラスには多くのコンストラクが定義されていると思いますが、引数に文字列だけを指定すると、その文字列がウィンドウのタイトルバーに表示されます。
frame.setSize(200, 100);
フレームクラスの setSize メソッドでウィンドウの横のサイズと縦のサイズを設定しています。インスタンスのメソッドやフィールドとアクセスするには . (ドット)演算子を使います。C++ では、インスタンスが変数である場合には .(ドット)演算子を使い、インスタンスがポインターである場合には ->(アロー演算子)を使いますが、Java では、ポインターという概念が存在しないことになっており、すべての場合に .(ドット)演算子でアクセスします。/li>
frame.setVisible(true);
ウィンドウを作成した時の初期値は非表示です。setVisible メソッドの引数に true を指定して、ウィンドウを表示する設定にしています。
実行結果
Hello.java を javac でコンパイル(Do Javac)します。そして作成された Hello.class を JBindery でアプリケーションとして保存します。作成されたアプリケーションをダブルクリックすると、アプリケーションが起動します。
このアプリケーションはウィンドウのクローズボタンをクリックしても、ウィンドウを閉じたり、アプリケーションを終了したりすることはできません。アプリケーションを終了するには、アップルメニューから Quit を選んでください。
Event driven
アプリケーションが起動してから、ウィンドウのクローズボタンがクリックされるなどのイベントが発生するまで何もせずに待機しているアプリケーションのことをイベントドリブン(event driven、イベント駆動)といいます。GUI アプリケーションはすべてイベントドリブンです。
そしてイベントを発生するものをイベントソース(event source)と呼びます。イベントソースは、多くの場合 GUI 部品(コンポーネント)です。そしてイベントを受け取って、それに対応する処理をするものをイベントリスナー(event listener)と呼びます。
先ほどのアプリケーションでは、イベントリスナーを設定していなかったため、ウィンドウを閉じたりすることができなかったのです。
Event Listener
イベントの受け手となるイベントリスナーはコンポーネント(GUI 部品)ごとに用意されています。ウィンドウには、WindowListener というものが用意されています。
なお、イベント発生源(イベントソース)となるコンポーネント(GUI 部品)には、最初からイベントを発生する設計になっています。
WindowListener
次のコードを Hello.java というファイル名で記述して、javac でコンパイルし、JBindery でアプリケーションとして保存してください。
なお、Java はファイル名とクラス名を同じにしなければならないので、このコーナーでは、ファイル名は Hello.java、クラス名は Hello と決めています。
Hello.java
import java.awt.*;
import java.awt.event.*;
class Hello implements WindowListener {
public static void main(String[] args) {
Frame frame = new Frame("WindowListener");
frame.setSize(200, 100);
frame.setVisible(true);
frame.addWindowListener(new Hello());
}
public void windowActivated (WindowEvent e) {}
public void windowClosed (WindowEvent e) {}
public void windowClosing (WindowEvent e) {System.exit(0);}
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified (WindowEvent e) {}
public void windowOpened (WindowEvent e) {}
}
サンプルコードをわかりやすくするために、WindowListener を main メソッドのある Hello クラスで採用する型にしましたが、実際には、WindowListener 用に新たに別のクラスを作る方法が良く使われるみたいです。
コード説明
import java.awt.event.*;
イベント取り扱うためには、java.awt.event.*; パッケージを読み込まなければなりません。
class Hello implements WindowListener {
implement をすべて実行すると意訳すればわかりやすいと思います。すべて実行するものとして windowListener を採用していす。このようにすべて実行するものとして用意されているものを、Java ではインターフェース(interface)と呼びます。
frame.addWindowListener(new Hello());
フレームに対してそのWindowListenerとなるものを設定しています。ここでのイベントリスナーは WindowListener を採用した、Hello クラス自身です。自身のクラスに対して、あらためて自身のクラスのインスタンスを作成するという奇妙な構文ですが、こういう記述をしなければコンパイルできないとしか今のところ説明できません。
public void windowActivated(WindowEvent e) {}
windowActivated は、ウィンドウ(フレーム)が、ユーザーからの操作に答えられる状態になった時に発生するイベントです。それに対して {} と何の処理もしていません。すべて実行すると言いましたが、何の処理をしないことを実行するという意味になります。何の処理もしない場合もこのように記述しなければコンパイル時にエラーになります。
public void windowClosed(WindowEvent e) {}
windowClosed は、ウィンドウ(フレーム)が閉じられた直後に発生するイベントです。ここでも何の処理もしません。
public void windowClosing (WindowEvent e) {System.exit(0);}
ウィンドウ(フレーム)のクローズボタンがクリックされた時に発生するイベントです。ここでは
System.exit を呼び出して、アプリケーションを終了しています。引数には通常 0 を指定します。このイベントに何の処理も書かなければアプリケーションを終了できないだけでなく、ウィンドウのクローズボタンをクリックしてもウィンドウは閉じなくなります。
public void windowDeactivated(WindowEvent e) {}
ウィンドウ(フレーム)が、ユーザーからの操作に答えられなくなった時に発生するイベントです。ここでも何の処理もしません。
public void windowDeiconified(WindowEvent e) {}
ウィンドウ(フレーム)が、最小化をやめた時に発生するイベントです。ここでも何の処理もしません。
public void windowIconified(WindowEvent e) {}
ウィンドウ(フレーム)が、最小化した時に発生するイベントです。ここでも何の処理もしません。
public void windowOpened(WindowEvent e) {}
ウィンドウ(フレーム)が、開いた時に発生するイベントです。ここでも何の処理もしません。
実行結果
ウィンドウのクローズボタンをクリックするとアプリケーションが終了します。
WindowAdapter
上記のアプリケーションでは、処理しないイベントのメソッドも記述しなければいけないので大変でした。そこですべてのイベントに対して何もしない処理を記述したイベントアダプタ(event adapter)というクラスが用意されています。そのクラスを継承すれば、対応するイベントのメソッドのみを上書き(override)すれば良いことになります。ウィンドウ(フレーム)に対しては、WindowAdapter というクラスが用意されています。
Hello.java
import java.awt.*;
import java.awt.event.*;
class Hello extends WindowAdapter {
public static void main(String[] args) {
Frame frame = new Frame("WinodwAdapter");
frame.setSize(200, 100);
frame.setVisible(true);
frame.addWindowListener(new Hello());
}
public void windowClosing(WindowEvent e) {System.exit(0);}
}
コード説明
class Hello extends WindowAdapter {
Java でクラスを継承する場合は、extends(拡張)というキーワードを使います。
public void windowClosing(WindowEvent e) {System.exit(0);}
見事に、処理を行うイベントのメソッドのみに処理を記述しています。メソッドシグネチャは先ほどの WindowListener の場合とまったく同じです。
実行結果
ウィンドウのクローズボタンをクリックするとアプリケーションが終了します。
Button
ボタン(tutton)は、ウィンドウの次にメジャーな GUI 部品(コンポーネント)でしょう。
Hello.java
import java.awt.*;
import java.awt.event.*;
class Hello extends WindowAdapter implements ActionListener {
static Frame frame;
boolean isHello = true;
public static void main(String[] args) {
frame = new Frame("Hello");
frame.setSize(200, 100);
frame.setLayout(new FlowLayout());
frame.addWindowListener(new Hello());
Button button = new Button("Greeting");
frame.add(button);
button.addActionListener(new Hello());
frame.setVisible(true);
}
public void windowClosing (WindowEvent e) {System.exit(0);}
public void actionPerformed(ActionEvent e) {
if (isHello) {
frame.setTitle("Goodbye");
isHello = false;
} else {
frame.setTitle("Hello");
isHello = true;
}
}
}
コード説明
class Hello extends WindowAdapter implements ActionListener {
クラスは 1 つのクラスを継承して、複数のインターフェイスを採用することができます。複数のインターフェイスを採用する場合は、implements A, B というようにカンマ(,)で区切ります。
ActionListener はボタンなどが発生するイベントに対応するイベントリスナーです。
static Frame frame;
インスタンスをグローバル変数にする場合は static 指定が必要です。
frame.setLayout(new FlowLayout());
ウィンドウに FlowLayout というレイアウト方法を設定しています。レイアウトを設定しないと、ウィンドウに配置される GUI 部品(コンポーネント)は、ウィンドウ一杯に広がります。
frame.add(button);
ウィンドウ(フレーム)の add メソッドで、引数の GUI 部品(コンポーネント)をウィンドウに配置します。
button.addActionListener(new Hello());
ボタンのイベントリスナーとして Hello クラスのインスタンスを指定しています。
frame.setVisible(true);
ウィンドウ(フレーム)の setVisible メソッドは、ウィンドウに配置された GUI 部品(コンポーネント)も表示状態に設定します。
public void actionPerformed(ActionEvent e) {
ボタンの ActionListener で宣言されているメソッドは、この 1 つだけです。なおインターフェースで宣言されているメソッドに実際に処理を定義する作業のようなことを、プログラミング用語では「実装 」と言います。
frame.setTitle("Goodbye");
ウィンドウ(フレーム)の setTitle メソッドで、ウィンドウのタイトルバーに表示される文字列を設定することができます。
実行結果
Greeting(挨拶)ボタンをクリックするたびに、ウィンドウのタイトルが Hello と Goodbye を繰り返します。
Label
ウィンドウの中に、文字列を表示するために一番良く使われる GUI 部品(コンポーネント)はラベル(label)でしょう。
Hello.java
import java.awt.*;
import java.awt.event.*;
class Hello extends WindowAdapter implements ActionListener {
static Label label;
boolean isHello = true;
public static void main(String[] args) {
Frame frame = new Frame("Greeting");
frame.setSize(200, 100);
frame.setLayout(new FlowLayout());
frame.addWindowListener(new Hello());
Button button = new Button("Greeting");
button.addActionListener(new Hello());
label = new Label("Hello");
frame.add(label);
frame.add(button);
frame.show();
}
public void windowClosing (WindowEvent e) {System.exit(0);}
public void actionPerformed(ActionEvent e) {
if (isHello) {
label.setText("Goodbye");
isHello = false;
} else {
label.setText("Hello");
isHello = true;
}
}
}
コード説明
label.setText("Goodbye");
ラベルの setText メソッドでラベルに表示される文字列を設定できます。なお getText メソッドを使うとラベルに表示されている文字列を取得できます。
ラベルも何かのイベントは発しているはずです。しかしラベルは本来、ユーザが文字列を入力したりなどの操作ができるものではありません。したがってラベルのイベントリスナーについては何も設定していません。
実行結果
Greeting(挨拶)ボタンをクリックするたびに、ラベルが Hello と Goodbye を繰り返します。
Posted: Jun. 29, 2020
Update: Jun. 30, 2020