第4章 イベント処理と GUI 部品
グラフィカルなユーザーインタフェース (GUI) を持つプログラムは、ユーザーがマウスのボタンを押したとき、キーボードのキーを押したときなどに何らかの反応を示さなければいけないことが多い。この章では、このような何らかの イ
ベントに反応するプログラムの書き方について学習する。
また、GUI 部品のボタンや、ユーザーがデータを入力するためのテキストフィー
ルドをユーザーインタフェースに付け加える方法についても学ぶ。
また、この章では、Java に特有のデータ型・クラスに関する話題（総称クラス・ゴミ集めなど）をいくつか紹介する。また、Java のプログラムで頻繁に利用することになる重要なメソッドなどもここで紹介する。
例外処理の try 〜 catch 文は C 言語にはない構文なので、ここで紹介する。

4.1 イベント処理
ユーザーがマウスボタンをクリックした、キーボードのキーを押した、などのイベントに対応するためには、と呼ばれるメソッドを定義する必要がある。
例題 4.1.1 マウスボタン
ファイル MouseTest.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;/* 1 */
4
5 public class MouseTest extends JPanel implements MouseLi
6private int x = 50, y = 20;
78public MouseTest() {9
setPreferredSize(new Dimension(150, 150));
10addMouseListener(this);/* 3 */
11}
12
13/* 4 */
14
public void mouseClicked(MouseEvent e) {15
x = e.getX();16
y = e.getY();17
repaint();
18
return;19}
20
21
public void mousePressed(MouseEvent e) {} /* 5 */22
public void mouseReleased(MouseEvent e) {} /* 5 */23
public void mouseEntered(MouseEvent e) {} /* 5 */24
public void mouseExited(MouseEvent e) {}/* 5 */
25
26@Override27
public void paintComponent(Graphics g) {28
super.paintComponent(g);29g.drawString("HELLO WORLD!", x, y);
30
}
31
32
public static void main(String[] args) { /* 省略 */33 }オブジェクト指向言語 第 4 章 p.1

このプログラムは、文字列を表示し、マウスがクリックされると、その場所に文字列を移動する。
いくつか注目すべき点がある。
まずイベントを扱うために java.awt.event.* を import している。
（/* 1 */）
イベントを扱うプログラムは大抵この import 文が必要になる。
さらにこのクラスが、mouseClicked というメソッドを持っていることを示すために、MouseListener というを implement していることを宣言している。（/* 2 */）コンストラクターで、addMouseListener(this) を呼んで、マウスのイベントを、this オブジェクトに結び付けている。（/* 3 */）（this は一般にメソッドを実行中のオブジェクト自身を指す。詳しくは後述する。 ここでは実質的には、mouseClicked メソッドを指す。）
mouseClicked というマウスボタンのクリックに対応するイベントハン
ドラーを定義している。（/* 4 */） mouseClicked メソッドはMouseEvent 型 の引数を受け取る。
MouseListener インタフェースの他のメソッド (mousePressed ,mouseReleased , mouseEntered , mouseExited ) は何もしないメソッドとして、いちおう定義しておく。（/* 5 */）このクラスは、文字列を表示する位置をフィールド x, y として保持している。
mouseClicked メソッドは、これらのフィールドを、マウスの押された位置にしたがって変更する。マウスの押された位置（単位はピクセル）を知るには、
MouseEvent クラスの getX , getY というメソッドを使う。そのあと repaintを呼び出して再描画を要求する。repaint は、JPanel クラスで定義済のメソッドで、その中で間接的に paintComponent メソッドを呼び出している。
自分で、呼出すコードを書かなくても、paintComponent メソッドが利用されている。オブジェクト指向言語に特有の振舞いである。
フィールドの宣言
フィールド（インスタンス変数）の宣言は、クラス定義の中に、メソッドの定義と同じレベルに（メソッドの定義の外に）並べて書く。フィールドはそのクラス中のすべてのメソッドから参照することができる。（ある意味でC言語の大域変数と似ている。）

オブジェクト指向言語 第 4 章 p.2

前述したようにクラスはオブジェクトの雛型である。MouseTest クラスに x, yというフィールドを宣言したということは、 MouseTest クラスのインスタンスが作られるときに、JPanel クラスが持っているすべての構成要素の他に、x,y という名前の、 int 型の構成要素ができるということである。
paintComponent メソッドと mouseClicked メソッドの中でこの x, y を参照
している。このようにメソッドの中で自分自身のフィールドやメソッド（スーパークラスで定義されているものも含む）を参照するときは、ピリオド（ドット）を使った記法は必要ない。
フィールドはオブジェクトが存在している間は値を保持している。これに対して、メソッドの中で宣言された変数（例えば、Othello.java の i や j）の寿命はメソッドの呼出しの間だけである。2 度め以降の呼び出しでも以前の値は保持していない。

4.2 this
this は、メソッドを所有しているオブジェクト自身を指す Java のキーワードである。他の言語では、self という言葉が使われることがある。
Java ではメソッドは基本的に次のような形で呼び出される。
object.method(arg1, arg2, …)
このとき、. の前に書かれているobject も内部的にはメソッドの引数の一つとして渡されている（でないと、フィールドや他のメソッドを参照できない）
が、他の引数と異なり名前がついていない。 これをメソッドの中で明示的に取り出すのが、this キーワードである。

4.3 インタフェース
インタフェース (interface）は、あるクラスが特定の名前と型のメソッドを持っていることを示すために使われる。そしてそのクラスのインスタンスが、示されたメソッドを必要とする場所で使用できることを示す。インタフェースは
C++ などにはない、Java 特有のメカニズムである。一言でいえば、メソッドの定義を持たず、のみを指定したクラスみたいなもののことである。Java は多重継承 （複数のスーパークラスを継承すること）を許さない
代わりに、このインタフェースという仕組みを提供している。
MouseListener インタフェースの定義 （ただし一部簡略化）
1 public interface MouseListener {2public void mouseClicked(MouseEvent e);
3
public void mousePressed(MouseEvent e);
4
public void mouseReleased(MouseEvent e);
5public void mouseEntered(MouseEvent e);
6public void mouseExited(MouseEvent e);
7 }例えば、インタフェース MouseListener の定義は、上のように
mouseClicked などのメソッドの引数、戻り値の型を宣言している。（このインタフェースの定義は、もともと用意されているので、自分でする必要はな

オブジェクト指向言語 第 4 章 p.3

い。） クラスと異なり、このメソッドの具体的な定義はインタフェース内のどこにもない。
あるクラスが、あるインタフェースを実装していることを宣言するためにはというキーワードを用いる。例えば、 addMouseListener の引数は MouseListener インタフェースを実装していなければならない。だからMouseTest クラスが MouseListener を実装していなければ、init メソッドの中の addMouseListener(this) はエラーになる。
Q 4.3.1 Foo という名前の JPanel を継承するクラスに mouseClicked などい
くつかのイベントハンドラーを定義して、マウスイベントに反応するプログラ
ムを作成するとき、import 文と public class Foo extends JPanel に続く 2 ワードを書け。
答: public class Foo extends JPanel
Q 4.3.2 mouseClicked メソッドの定義の中で repaint() の呼出しがなけれ
ば、MouseTest.java はどのような振舞いをするか?
答:
問 4.3.3 円を描画し、円の内部をマウスでクリックすると「あたり」、円の外部をクリックすると「はずれ」という文字列を描画するプログラムを書け。
問 4.3.4 § 3.3 の問 3.3.6 で作成した 2 次元の色のグラデーションを作成する
GUI アプリケーションを改良して、マウスをクリックした位置の色で何かの文字列を描画する GUI アプリケーション（カラーピッカー）を作成せよ。
また、カラーピッカーを利用して、16 × 16 などのサイズのドット絵を作成するプログラムを書け。
問 4.3.5 § 3.4 の Othello.java を改良して、マウスで指示をすると石を置けるようにせよ。つまり、盤面をクリックすると、空→白丸→黒丸→空→…の順に変わるようにせよ。

4.4 キーボードイベント
次の例題はマウスではなく、キーボードからのイベントを扱う。メソッド名やクラス名の Mouse が Key に変わるだけで、大部分は MouseTest.java に似ている。
例題 4.4.1 （参考） キーボード
U(p), D(own) の各キーが押されると文字列が移動する。
ファイル KeyTest.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class KeyTest extends JPanel implements KeyListen
6
private int x = 50, y = 20;
78public KeyTest() {9
setPreferredSize(new Dimension(150, 150));
10
setFocusable(true);

オブジェクト指向言語 第 4 章 p.4

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 }

}

addKeyListener(this);@Override
public void paintComponent(Graphics g) {super.paintComponent(g);g.drawString("HELLO WORLD!", x, y);}public void keyTyped(KeyEvent e) {int k = e.getKeyChar();if (k == 'u') {y -= 10;} else if (k == 'd') {y += 10;}
System.err.printf("key = %d%n", k);repaint();}
public void keyReleased(KeyEvent e) {}public void keyPressed(KeyEvent e) {//int k = e.getKeyCode();//if (k == VK_U) {//y -= 10;//} else if (k == VK_D) {//y += 10;//}//
System.err.printf("key=%d", k);//repaint();}
public static void main(String[] args) { /* 省略 */KeyListener インタフェース は keyPressed , keyReleased , keyTyped の3つのメソッドからなる。このうちの keyPressed が「キーが押し下げられた」とき、keyReleased が「キーが離された」とき、に対応するイベントハン
ドラーである。実際に押されたキーに対応する文字を知るには KeyEvent クラ
ス の getKeyCode というメソッドを用いる。keyTyped は、keyPressed,
keyReleased よりも高レベルなイベントで「文字が入力された」ときに対応するイベントである。このメソッドでは、KeyEvent クラスの getKeyChar メソ
ッドを用いて、入力された文字を知ることができる。（つまり、Shift キーを押しながら, “a” キーを押した場合は 'A' という文字が返る。）
Q 4.4.2 Barという名前の JPanel を継承するクラスに keyTyped などいくつかのイベントハンドラーを定義して、キーイベントに反応するプログラムを作成するとき、import 文と public class Bar extends JPanel に続く 2
ワードを書け。
答: public class Bar extends JPanel

オブジェクト指向言語 第 4 章 p.5

問 4.4.3 KeyTest.java を拡張して、上下に加えて左右にも文字列を動かせる
ようにせよ。
さらにカーソルキー（矢印キー）を利用する方法を調べよ。 KeyTest.java
を改良して、カーソルキーで文字を動かせるようにせよ。（ヒント: keyTypedではなく、keyPressed メソッドを使う必要がある。）
参考:https://docs.oracle.com/javase/jp/15/docs/api/java.base/java/awt

4.5 GUI 部品
大抵の GUI は、ボタン、テキストフィールド、ラベル、チェックボックスなどの GUI部品から構成されている。

ボタンの例

テキストフィールドの例(ChangeColor.java)(Factorial.java)

プログラムは、ボタンが押された、テキストフィールドが書き換えられた、などのイベントにも反応しなければならない。このようなイベントに対して、
mouseClicked や keyPressed のような低レベルなイベントハンドラーで対応するのは、不可能ではないにしても困難である。そこで GUI 部品に対するイ
ベントにはというイベントハンドラーが用意されている。

このイベントハンドラーは ActionEvent 型の引数を受け取る。ActionEvent型の引数は、イベントが発生した場所・時間に関する情報などを持っていて、この引数から、どの部品でイベントが発生したかを特定することができる。
例題 4.5.1 ボタンを押すとテキストの色が変わる。
ファイル ChangeColor.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class ChangeColor extends JPanel
6
implements ActionListener {7
private final Color[] cs = {8Color.RED, Color.BLUE, Color.GREEN, Color.ORANGE
9};10
private int i = 0;
11
private JLabel label;
12
13public ChangeColor() {14
JButton b = new JButton("Next");
15
b.addActionListener(this);/* 1 */
16
label = new JLabel("HELLO WORLD!");17label.setForeground(cs[i]);/* 前景色の変18
setLayout(new FlowLayout());/* 2 */
19
add(b); add(label);/* 3 */
20}
21

オブジェクト指向言語 第 4 章 p.6

22
23
24
25
26
27
28 }

public void actionPerformed(ActionEvent e) {i = (i + 1) % cs.length;label.setForeground(cs[i]);}public static void main(String[] args) { /* 省略 */新しいボタンを作成するのに、JButton クラス のコンストラクターを用いる。
このコンストラクターは、ボタンに表示する文字列を引数に取る。JLabel は単に文字を表示するためだけの GUI 部品である。生成した部品を GUI アプリケー
ションの画面に加えるにはというメソッドを用いる。 (/* 3 */)その直前の行 (/* 2 */) では、add された部品を配置する方法を指定している。ここでは FlowLayout という単純な配置方法を選択している。ちなみに
JPanel の場合は、デフォルトのレイアウトが FlowLayout なので、この行はなくても構わない。
actionPerformed はインタフェース のメソッドである。

このインタフェースには、他のメソッドはなく、actionPerformed というただ一つのメソッドのみ宣言されている。ボタン b が押されたときにactionPerformed が呼ばれるように、ボタン b の addActionListener メ
ソッドを読んでいることに注意する。(/* 1 */)この例題では、イベントが発生する GUI 部品を 1 つしか使用していないので、
actionPerformed メソッドの引数 (e) は調べる必要がない。
actionPerformed が呼び出される度に、フィールド i の値が変更される。
（イベントが発生する GUI 部品を 2 つ以上使う例はあとで紹介する。）
Q 4.5.2 Baz という名前の JPanel を継承するクラスに actionPerformed イ
ベントハンドラーを定義して、ボタンなどのイベントに反応するプログラムを作成するとき、import文と public class Baz extends JPanel に続く 2
ワードを書け。
答: public class Baz extends JPanel

例題 4.5.3 テキストフィールドに数字を入力して、その階乗を計算する。
ファイル Factorial.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class Factorial extends JPanel implements ActionL6private JTextField input;
7
private JLabel output;
8
9
public Factorial() {10
setPreferredSize(new Dimension(300, 50));
11
input = new JTextField("0", 8);

オブジェクト指向言語 第 4 章 p.7

12
output = new JLabel("
1");
13
input.addActionListener(this);
14
setLayout(new FlowLayout());
15
add(input); add(new JLabel("の階乗は"));
16
add(output); add(new JLabel("です。"));
17
}
18
19
private static int factorial(int n) { // factorial -20
int r = 1;
21
for (; n > 0; n--) {22
r *= n;23}
24
return r;
25
}
26
27
public void actionPerformed(ActionEvent e) {
28
try {
29
int n = Integer.parseInt(input.getText());
30
output.setText(" " + factorial(n)); /* ラベルの表示
31} catch (NumberFormatException ex) {32
input.setText("数値!");
33
}
34
}
35
36
public static void main(String[] args) { /* 省略 */ }37 }JTextField のコンストラクターは、最初に表示する文字列 （String 型）と、表示できる文字数 （int 型）の 2 つの引数を取る。
ユーザーがテキストフィールドに文字を書き込み、リターンキーを押した時点
でイベントが発生する。テキストフィールドの場合もボタンと同じくactionPerformed メソッドで処理する。入力された文字列はactionPerformed の中で input（JTextFieldクラス）の getText メソッ
ド を使って知ることができる。
このあと output（JLabelクラス）の setText というメソッドを呼び出して、ラベルに表示されている文字列を変更している。
は文字列から整数に変換するためのメソッド（java.lang.Integer クラスのクラスメソッド）である。
java.lang.Integer クラス:
public static int parseInt(String s)
文字列の引数を符号付き 10 進数の整数型として構文解析した結果生成された整数値が返される。
階乗の計算はクラスメソッド factorial として独立させた。
このメソッドは戻り値を持つが、return 文の書き方も C 言語と同じである。

オブジェクト指向言語 第 4 章 p.8

戻り値型 メソッド名（引数の型 引数名, …） {…
}というメソッドの定義の書き方も（戻り値型のまえに public などの修飾子がつくことがあることを除けば）C 言語の関数の書き方と同じである。
Q 4.5.4 str という String 型の変数に "123" のような整数を表す文字列が入っているとき、これを 123 という int 型に変換した値を返す Java の式を書け。
答:問 4.5.5 第 3 章の N_gon.java の正多角形の辺の数をテキストフィールドから入力できるようにせよ。

4.6 Java の例外処理
try 〜 catch 〜 文 は
try ブロック 1 catch (例外型 変数) ブロック 2という形で用いる。
この形は、まずブロック1を実行する。この中でエラーが起こらなければ、そのまま次へ進む。ブロック1の中で例外 （エラーと考えて良い）と呼ばれる状況が起こったとき、 catchの後ろの例外型がその例外の型とマッチするか調べ、マッチすればその後のブロック2を実行する。 catch (例外型 変数)ブロック
という形（catch 節）が複数続いても良い。その場合は発生した例外にマッチする例外型を持つ、最初の catch 節が選択される。“変数”に例外の情報を持つ
オブジェクトが初期値として渡されてブロックが実行される。また、Java 7 以
降では、“例外型”を“|”で区切って、複数個列挙できるようになった。 catch(例外型 1 | 例外型 2 | … | 例外型 n 変数)ブロック のように catch 節を書くと、例外が例外型1, 例外型2, …, 例外型n のいずれかにマッチするとき、後ろのブロックが実行される。マッチするものがなければ、現在実行しているメソ
ッドを呼出した式を囲んでいる try 〜 catch 文を探す。それもなければ、さらにメソッド呼出しの履歴をさかのぼって、囲んでいる try 〜 catch 文を探す。
それでもなければプログラムを終了する。
また、最後に finally ブロック という形（finally 節）がつく場合もある。その場合、finally ブロックは例外が起こったか否か、さらに例外が catch されたか否かにかかわらず、必ず実行される。
例えば、0 による除算を行なうと ArithmeticException という種類の例外が発生する。次のようなプログラムを実行すると、ファイル TryCatchTest.java
1 public class TryCatchTest {2
public static void main(String[] args) {3
int i;
4for (i = -3; i <= 3; i++) {
5
try {
6
System.out.printf("10 / %d = %d%n", i, 10 / i);

オブジェクト指向言語 第 4 章 p.9

7} catch (ArithmeticException e) {8
System.out.println("エラー: " + e.toString());
9
}
10
}
11
System.out.println("終");
12
}
13 }

出力は次のようになる。
10 / -3 = -3
10 / -2 = -5
10 / -1 = -10
エラー: java.lang.ArithmeticException: / by zero
10 / 1 = 10
10 / 2 = 5
10 / 3 = 3
終i が 0 になった地点で例外が発生し、catch の後のブロックが実行される。その後は、try 〜 catch 文の次の文の実行を継続する。
Q 4.6.1 次のプログラムの出力を予想せよ。
1 public class TryCatchTest2 {2public static void main(String[] args) {3
int i;4try {5for (i = -3; i <= 3; i++) {6
System.out.printf("10 / %d = %d%n", i, 10 / i);7}8} catch (ArithmeticException e) {9
System.out.println("エラー: " + e.toString());
10}
11
System.out.println("終");
12
}
13 }

答:
10 / -3 = -3
10 / -2 = -5
10 / -1 = -10
エラー: java.lang.ArithmeticException: / by zeroArithmeticException の他に、よく扱う必要のある例外としては次のようなものがある。いずれも java.lang パッケージに属する。 java.lang パッケー
ジは標準的なクラスを集めた、import の必要がない（最初から import されている）パッケージである。
NullPointerException

null が通常のオブジェクトとしてア

オブジェクト指向言語 第 4 章 p.10

クセスされた
Integer.parseInt で文字列が数値として解釈できない

NumberFormatException

ArrayIndexOutOfBoundsException 範囲外の添字で配列がアクセスされた
null は、として使われる定数である。（C 言

語の NULL に対応する。）
例外の中には、発生する可能性があるときは try 〜 catch で囲んで処理する必要があるもの（検査例外、checked exception）もある。入出力に関する例外のjava.io.IOException などである。

4.7 throw 文
プログラムにより例外を発生させるには throw 文を用いる。
throw 式;
この“式”は例外型（Exception あるいはそのサブクラス）のオブジェクトでなければならない。
次の例は、コマンドライン引数（main メソッドの引数の文字列の配列 args）
として渡された数字の積を計算するプログラムである。途中で 0 が出てきた場
合は、わざと例外を発生させて、残りのかけ算の処理を行なわないようにしている。（ただしこのプログラム例では、break 文を用いる方が自然である。）
ファイル TryCatchTest2.java
1 public class TryCatchTest2 {2public static void main(String[] args) {3
int i, m = 1;
4
try {
5
for (i = 0; i < args.length; i++) {6m *= foo(args[i]);7}8} catch (Exception e) {9m = 0;
10}
11
System.out.println("答は " + m + " です。");
12
}
13
14
public static int foo(String arg) throws Exception {15
int a = Integer.parseInt(arg);
16
if (a == 0) throw new Exception("zero");17
return a;
18
}
19 }

例えば “java TryCatchTest2 1 2 0 3 4 5 6” というコマンドライン引数で実行させると、3番目の引数の 0 を呼んだ時点で、例外を発生させるため、残りの引数の 3, 4, 5, 6 は無視される。
上の foo メソッドのように本来 try 〜 catch で処理する必要のある例外を、メソッド内で処理しないメソッドは、 throws というキーワードのあとに発生

オブジェクト指向言語 第 4 章 p.11

する可能性のある例外をコンマ (,) で区切って列挙しなければならない。

4.8 String クラスの split メソッド
例題 4.8.1 文字列の分割
数値の配列のデータを空白区切りの文字列で渡せるように、 Graph.java を拡張する。
ファイル Graph2.java
1 import java.awt.*;
2 import javax.swing.*;
3 import java.awt.event.*;
4
5 public class Graph2 extends JPanel implements ActionList
6private int[] is = {};7
private JTextField input;
8
private final Color[] cs = {Color.RED, Color.BLUE};
9
private final int scale = 15;1011public Graph2() {12
setPreferredSize(new Dimension(200, 200));
13
input = new JTextField("", 16);
14
input.addActionListener(this);
15
setLayout(new FlowLayout());
16
add(input);
17
}
18
19
@Override20
public void paintComponent(Graphics g) {21
super.paintComponent(g);22
int i;
23
int n = is.length;2425
for (i = 0; i < n; i++) {26
g.setColor(cs[i % 2]);
27
g.fillRect(0, i * scale + 30, is[i] * scale,
28
}
29
}
30
31
public void actionPerformed(ActionEvent e) {32
String[] args = input.getText().split(" ");33
int n = args.length;34
is = new int[n];3536int i;
37
for(i = 0; i < n; i++) {38
is[i] = Integer.parseInt(args[i]);39}40repaint();
41
}
42
43
public static void main(String[] args) { /* 省略 */44 }オブジェクト指向言語 第 4 章 p.12

ここでは、空白区切りの文字列を文字列の配列に分割するためにString クラスのメソッドを用いた。
java.lang.String クラス:
public String[] split(String regex)
この文字列を、指定された正規表現 (regex) に一致する位置で分割する。

さらに Integer.parseInt メソッドで文字列から整数へ変換している。上のactionPerformed メソッドの中身は、空白で区切られた文字列を配列に変換する典型的な方法である。
split メソッドの引数は、区切りに使用する文字列を表す正規表現である。これを "," に変更すると、コンマで区切られた文字列を分割することができる。
にすると、空白文字が 2 つ以上連続したり、タブ文字などが混また、ざったりという場合にも対応できる。Java で使用できる正規表現については、
java.util.regex.Pattern クラスのドキュメント（https://docs.oracle.com/javase/jp/15/docs/api/java.base/java/utを参照すること。
Q 4.8.2 str という String 型の変数に "087-864-2015" という文字列が入っているとき、これを '-' 区切りで分割した、String 型の配列を返す Java の式を書け。
答:
問 4.8.3 テキストフィールドに与えられた数値データから折れ線グラフを生成する GUI アプリケーションを書け。（例外
ArrayIndexOutOfBoundsException が出ないように注意すること。 n 個の点を結ぶ線は n - 1 本であることに注意する。）

棒グラフ

折れ線グラフ文字によるグラフ

4.9 配列の生成
new オペレーターは配列を生成するときにも使用することができる。
は、動的に長さ n の （int 型の）配列を生成する式である。int の代
わりに他の型名を使うとその型の配列が生成される。C の配列宣言とは異なり、オブジェクト指向言語 第 4 章 p.13

要素数 n の値がコンパイル時に定まっている必要はない。この形式を使うと配列の各要素は 0（オブジェクト型の場合は null）に初期化される。
一方、は、要素数を指定するのではなく、初期値を列挙して（int 型の）配列を生成する式である。
なお、配列変数の宣言と同時に初期値を指定するときは、new 演算子を使わず、次のように単にブレースの中に初期値を列挙することができる。
1

int[] arr = {1, 7, 4, 10};

この宣言の = の右辺 {1, 7, 4, 10} は文法的には式ではないので、変数の宣言時でなければ使えない。
Q 4.9.1 次の Java プログラム（の一部）の文法的な誤りを指摘せよ。また、どう修正すればよいか？
1
2
3
4
5
6
7
8
9
10
11
12
13

…
int[] arr;
if (x > 0) {arr = { 1, 2, 3, 4 };} else {arr = { 5, 6, 7 };}for (int i = 0; i < arr.length;; i++) {printf("%d, ", arr[i]);}…

例題 4.9.2 時間のデータを “9:45 12:35 4:42”というように、空白で区切って渡し、その時間の合計を表示する。
ファイル AddTime2.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class AddTime2 extends JPanel implements ActionLi
6private JTextField input; // e.g. 2:45 1:25 3:34 2:4
7
private JLabel output;
8
9
public AddTime2() {10
setPreferredSize(new Dimension(180, 150));
11
input = new JTextField("1:23 4:56", 16);
12
output = new JLabel("00:00");
13
input.addActionListener(this);
14
setLayout(new FlowLayout());
15
add(input);16
add(new JLabel("の和は"));
17
add(output);18
add(new JLabel("です。"));
19}
20

オブジェクト指向言語 第 4 章 p.14

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 }

private static int[] addTime(int[] t1, int[] t2) { /int[] t3 = { t1[0] + t2[0], t1[1] + t2[1] }; //}if (t3[1] >= 60) { // 繰り上がりの処理
t3[0]++;
t3[1] -= 60;}
return t3; // 新しい配列を返す。

public void actionPerformed(ActionEvent e) {String[] args = input.getText().split("\\s+");int[] t = {0, 0};for (String s: args) {String[] stime = s.split(":");
t = addTime(t, new int[] { Integer.parseInt// addTimeの呼出し前にその引数に入っていた配列は不// あとでGCされる。

}}
output.setText(String.format("%02d:%02d", t[0],public static void main(String[] args) { /* 省略 */addTime はその中で配列を確保して戻り値に用いている。このように new は、
C 言語の malloc に近い働きをする。また、このようにして確保された配列
は、init の中で t = addTime(t, …) という呼出しで次々と使われなくなるが、使われなくなったメモリ領域は(Garbage Collection, GC) によって自動的に回収される。（C 言語のように free による明示的なメモリの解放は必要ない。） GC のある言語ではこのように次々と新しいデータを生成して、古いデータを捨てるというスタイルが可能になる。

4.10 総称クラスの使用
総称クラス (generic class) は、型パラメーターを持つクラスのことで、Java 5 から導入された。代表的な総称クラスの例として ArrayList, HashMap,
LinkedList, ArrayDeque などがあげられる。型パラメーターはに書かれる。
ArrayList はのようなものである。（通常の配列と異なり、各要素の定数時間のアクセスはできない。） ArrayList の型パラ
メーターは要素の型を表す。（総称クラスはこのようにコレクション（データの集まり）の型に使われることが多い。）例えば、String 型を要素とする
ArrayList は ArrayList<String> となり、次のように使用する。
// コンストラクターは空の ArrayList 作成
ArrayList<String> arr1 = new ArrayList<String>();オブジェクト指向言語 第 4 章 p.15

// データ追加
arr1.add("aaa"); arr1.add("bb");// データ取出し
String s = arr1.get(1);arr1.add("cccc");add メソッドでデータを追加し、get メソッドでデータを取り出すことができる。 ArrayList の無引数のコンストラクターは空の ArrayList を生成する。
本来は総称クラスのコンストラクターは型パラメーターが必要だが、Java 8 か
らは文脈から推論できる場合、次のように省略できるようになった．
ArrayList<String> arr1 = new ArrayList<>();
Q 4.10.1 Color 型の要素を持つ ArrayList の colors という名前の変数を、
空の ArrayList に初期化する宣言を書け。
答:int, double のようなプリミティブ型は総称クラスの型パラメーターになることができないという制限があるので注意が必要である。（型の名前が小文字で始まるので区別できる。）このときは Integer, Double などの対応すると呼ばれるクラスを利用する。Java の主なプリミティブ型とラッパ
ークラスとの対応を以下に挙げる。
プリミティブ型 ラッパークラス
int

Integerchar

CharacterdoubleDoublebooleanBoolean

ここに挙げている以外のプリミティブ型 (byte, short, long, float) に対応するラッパークラスは単にプリミティブ型の先頭の文字を大文字にすれば良い。
ラッパークラスとプリミティブ型の変換はほとんどの場合、自動的に行われる（オートボクシング）ので、型パラメーターとして int の代りに Integer と書く以外は通常のクラス型をパラメーターとするときと変わらない。例えば次のように書くことができる。
// コンストラクターは空の ArrayList 作成
ArrayList<Integer> arr2 = new ArrayList<>();// データ追加
arr2.add(123); arr2.add(456); arr2.add(789);// データ取出し
int i = arr2.get(1);ArrayList<String> に int 型の要素を add したり、
ArrayList<Integer> から String 型の要素を get したりするのは、当然型
エラー（コンパイル時のエラー）になる。
ArrayList<String> arr1 = new ArrayList<> ();arr1.add(333);// 型エラー
ArrayList<Integer> arr2 = new ArrayList<> ();…
String t = arr2.get(2); // 型エラー

オブジェクト指向言語 第 4 章 p.16

このような型エラーをコンパイル時にちゃんと発見したい、というのが、総称
クラスの導入のそもそもの動機である。
API ドキュメントの中では、型パラメーターは E のような仮のクラス名が使われ、java.util.ArrayList<E> クラス:
public ArrayList()
空のリストを作成します。
public boolean add(E e)
リストの最後に、指定された要素 (e) を追加します。
public E get(int index)
リスト内の指定された位置 (index) にある要素を返します。
のように書かれる。
Q 4.10.2 double 型を保存するための ArrayList の ds という名前の変数を空の ArrayList に初期化する宣言を書け。（ヒント: double はプリミティブ型である。）
答:
例題 4.10.3 マウスクリックの位置を保存する
描画データの一時保存に ArrayList を使用する例である。 mouseClicked メ
ソッドでクリックされた座標を保存し、 paintComponent メソッドでそれを利用している。なお、配列型は総称クラスの型パラメーターとして問題なく使用することができる。実際、ラッパークラスは要素数 1 の配列のようなものである。この例の場合、クリックされる回数が前もってわからないので、ArrayList を使用している。
ファイル MouseDraw.java
1 import java.awt.*;
2 import javax.swing.*;
3 import java.awt.event.*;
4 import java.util.ArrayList;
5
6 public class MouseDraw extends JPanel implements MouseLi
7private ArrayList<int[]> points;
89public MouseDraw() {10
setPreferredSize(new Dimension(150, 150));
11
points = new ArrayList<>();
12
addMouseListener(this);
13
}
14
15
public void mouseClicked(MouseEvent e) {16
points.add(new int[] { e.getX(), e.getY() });17
repaint();
18
}
19
20
public void mouseEntered(MouseEvent e) {}21
public void mouseExited(MouseEvent e) {}22
public void mousePressed(MouseEvent e) {}23
public void mouseReleased(MouseEvent e) {}24
25@Override

オブジェクト指向言語 第 4 章 p.17

26
27
28
29
30
31
32
33
34
35
36
37
38 }

public void paintComponent(Graphics g) {super.paintComponent(g);}int i, n = points.size();for (i = 1; i < n; i++) {int[] p0 = points.get(i - 1);
int[] p1 = points.get(i);g.drawLine(p0[0], p0[1], p1[0], p1[1]);}public static void main(String[] args) { /* 省略 */例題 4.10.4 色の名前
HashMap はと呼ばれるデータ構造である。通常の配列と異なり、int

型だけではなく、任意の型（String 型など）をキー（添字）として、要素を格納・検索することができる。 HashMap の型パラメーターは 2 つあり、1 つめがキーの型、2 つめが要素の型である。下の例では、HashMap<String,
Color>、 つまりキーが String 型で要素が Color 型の連想配列を用いている。要素の格納には put メソッド、検索には get メソッドを用いる。
java.util.HashMap<K,V> クラス:
public HashMap()
空の HashMap を作成します。
public V put(K key, V value)
指定された値 (value) と指定されたキー（key）をこのマップに関連付けます。
public V get(Object key)
指定されたキー (key) がマップされている値を返します。
Object (java.lang.Object) クラスは Java のすべてのクラスのスーパークラ
スとなる、クラス階層のルートクラスである。get メソッドの引数の型として、Object 型が使われている。
ファイル ColorName.java
1 import java.awt.*;
2 import javax.swing.*;
3 import java.awt.event.*;
4 import java.util.HashMap;
5
6 public class ColorName extends JPanel implements ActionL
7private HashMap<String, Color> hm;
8
private JTextField input;
910
public ColorName() {11
setPreferredSize(new Dimension(250, 120));12// http://www.colordic.org/w/ より抜粋
13
hm = new HashMap<>();
14
hm.put("鴇", new Color(0xf7acbc)); hm.put("赤",オブジェクト指向言語 第 4 章 p.18

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 }

}

hm.put("朱", new Color(0xf26522)); hm.put("桃",hm.put("緋", new Color(0xaa2116)); hm.put("肌",hm.put("橙", new Color(0xf47920)); hm.put("褐",hm.put("黄", new Color(0xffd400)); hm.put("鶸",hm.put("鶯", new Color(0x87943b)); hm.put("緑",hm.put("鉄", new Color(0x005344)); hm.put("水",hm.put("青", new Color(0x009ad6)); hm.put("藍",hm.put("紺", new Color(0x003a6c)); hm.put("菫",hm.put("藤", new Color(0xafb4db)); hm.put("紫",hm.put("白", new Color(0xfffffb)); hm.put("灰",hm.put("黒", new Color(0x130c0e)); hm.put("紅",input = new JTextField("紅 白 紺", 8);
input.addActionListener(this);
setLayout(new FlowLayout());
add(input);@Override
public void paintComponent(Graphics g) {String text = input.getText();
super.paintComponent(g);g.setFont(new Font("SansSerif", Font.BOLD, 64));
String[] colors = text.split("\\s+");for (int i = 0; i < colors.length; i++) {String c = colors[i];Color color = hm.get(c);if (color == null) {color = Color.BLACK;}
g.setColor(color);
g.drawString(c, 64 * i, 100);}}
public void actionPerformed(ActionEvent e) {repaint();}
public static void main(String[] args) { /* 省略 */問 4.10.5 総称クラス java.util.LinkedList, java.util.ArrayDeque の使用法を調べ、プログラムを作成せよ。

4.11 複数の GUI 部品を使用したプログラム例
例題 4.11.1 ボタン 2 つを使ってテキストを左右に移動する。
ファイル LeftRightButton.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4

オブジェクト指向言語 第 4 章 p.19

5 public class LeftRightButton extends JPanel implements A
6private int x = 20;
7
private JButton lBtn, rBtn;
89public LeftRightButton() {10
setPreferredSize(new Dimension(200, 70));
11lBtn = new JButton("Left");
12
rBtn = new JButton("Right");
13lBtn.addActionListener(this);
14
rBtn.addActionListener(this);
15
setLayout(new FlowLayout());
16
add(lBtn); add(rBtn);
17
}
18
19
@Override20
public void paintComponent(Graphics g) {21
super.paintComponent(g);22g.drawString("HELLO WORLD!", x, 55);
23
}
24
25
public void actionPerformed(ActionEvent e) {26
Object source = e.getSource();27
if (source == lBtn) {// lBtnが押された
28
x -= 10;29}30
else if (source == rBtn) { // rBtnが押された
31
x += 10;32}
33
repaint();
34
}
35
36
public static void main(String[] args) { /* 省略 */37 }このプログラムでは GUI 部品（ボタン）を 2 つ使用しているので、どのボタンが押されたかを actionPerformed メソッド中で調べる必要がある。そのために ActionEvent クラス の getSource というメソッドを用いて、比較演算子(==) で比べることによって、イベントの起こったボタンを特定している。
問 4.11.2 摂氏の温度をテキストフィールドに入力して、これを華氏の温度に変換する GUI アプリケーションを Factorial.java（例題 4.5.3）にならって書け。（ただしボタンは使わない。）
さらに、2 つのテキストフィールドを用いて、摂氏と華氏の変換を双方向に行なえる （片方のテキストフィールドの値を変えると、もう片方のテキストフィ
ールドの値が変わる）ようにせよ。

（参考） （華氏の温度） = （摂氏の温度） × 1.8 + 32

例えば摂氏 0 度は華氏 32 度、摂氏 100 度は華氏 212 度になる。また、華氏 0

オブジェクト指向言語 第 4 章 p.20

度は摂氏 -17.8 度、華氏 100 度は摂氏 37.8 度となる。華氏は、人間が通常生活できる気温が 0 〜 100 の範囲に収まるようにしたものである。
（参考） String 型を double 型（実数の型）に変換するには、というjava.lang.Double クラスのクラスメソッドを使う。
java.lang.Doubleクラス:
public static double parseDouble(String s)
指定された String が表す値に初期化された新しい double 値を返す。
Integer.parseInt と使い方が似ているが、double 型を返す。
また逆に、double 型をString 型に変換するときに、書式を指定したい（例えば 小数点以下を 3 桁以内に抑えたい）ときは、というク

ラスメソッド を使う。
java.lang.Stringクラス:
public static String format(String format,
Object... args)指定された書式の文字列と引数を使って、書式を整えた文字列を返す。
引数の意味は PrintWriter クラスの printf メソッド
（System.out.printf など）と同じだが、標準出力に出力するのではなく戻り値として文字列を返す。
Q 4.11.3 str という String 型の変数に "3.14" という文字列が入っているとき、これを 3.14 という double 型に変換した値を表す Java の式を書け。
答:
Q 4.11.4 x という double 型の変数に1.0 / 3 という式の結果が入っているとき、これを "0.33" という小数第 2 位までの String 型に変換した値を表す
Java の式を書け。
答:

4.12 内部クラス
一方、GUI 部品が多くなってきたときは、if 〜 else 文が何重も入れ子になってしまう getSource メソッドを用いる方法は効率が悪い。次の例のように（インナークラス, inner class） を用いるほうが効率が良い。
例題 4.12.1 LeftRightButton.java を内部クラスを用いて書き換える
ファイル LeftRightButton2.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class LeftRightButton2 extends JPanel {6private int x = 20;
78public LeftRightButton2() {9
setPreferredSize(new Dimension(200, 70));

オブジェクト指向言語 第 4 章 p.21

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 }

}

JButton lBtn = new JButton("Left");
JButton rBtn = new JButton("Right");lBtn.addActionListener(new LeftListener());
rBtn.addActionListener(new RightListener());
setLayout(new FlowLayout());
add(lBtn); add(rBtn);

private class LeftListener implements ActionListenerpublic void actionPerformed(ActionEvent e) {x -= 10;
repaint();}}
private class RightListener implements ActionListene
public void actionPerformed(ActionEvent e) {x += 10;
repaint();}}@Override
public void paintComponent(Graphics g) {super.paintComponent(g);g.drawString("HELLO WORLD!", x, 55);}
public static void main(String[] args) { /* 省略 */Java ではクラスの中にクラスを定義することができる（これが内部クラスである）。これは関数の中に関数を定義できない C との大きな違いである。上の例
は、この内部クラス（LeftListener と RightListener）を用いて、actionPerformed メソッドを与えている。内部クラスの中では、その外側のクラスのフィールド（上の例の場合 x）やメソッドなど（上の例の場合
repaint メソッド）を参照することができる。
このように内部クラスを用いると、addActionListener のときに、コンポー
ネントとメソッドを関連づけることができるので、コンポーネントの数が多い
ときは getSource メソッドを用いるよりも効率が良い。

4.13 匿名クラス
内部クラスに名前をつけずに（,, anonymous class）そのインスタンスを生成することができる。名前のないクラスのオブジェクトは
次のような式で作成する。
new スーパークラスのコンストラクター(引数) {メソッド・フィールドの定義}

オブジェクト指向言語 第 4 章 p.22

この形式の前半（この色の部分）は通常のコンストラクターの呼出しと同じカタチで、後半（この色の部分）はクラスの定義の本体（{ と } の間）に同じカタチである。
スーパークラスのコンストラクターは ActionListener のようなインタフェース名でも良い。その場合は下の例のように引数はとらず、() のみを書く。また、その場合のスーパークラスは java.lang.Object となる。
例題 4.13.1 LeftRightButton.java を匿名クラス (anonymous class) を用いて書き換える、
ファイル LeftRightButton3.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class LeftRightButton3 extends JPanel {6private int x = 20;
78public LeftRightButton3() {9
setPreferredSize(new Dimension(200, 70));
10JButton lBtn = new JButton("Left");
11
JButton rBtn = new JButton("Right");
12lBtn.addActionListener(new ActionListener() {13
public void actionPerformed(ActionEvent e) {14
x -= 10;15
repaint();
16
}
17
});
18
rBtn.addActionListener(new ActionListener() {19
public void actionPerformed(ActionEvent e) {20
x += 10;21
repaint();
22
}
23
});
24
setLayout(new FlowLayout());
25
add(lBtn); add(rBtn);
26
}
27
28
@Override29
public void paintComponent(Graphics g) {30
super.paintComponent(g);31g.drawString("HELLO WORLD!", x, 55);
32
}
33
34
public static void main(String[] args) { /* 省略 */35 }4.14 final 修飾子と実質的に final
内部クラス（匿名クラスを含む）はメソッドの中で定義することも可能で、その場合はメソッドの局所変数を参照することもできるが、少し制限がある。

オブジェクト指向言語 第 4 章 p.23

実装上の都合で、内部クラスを生成するとき、参照されているメソッドの局所変数についてはコピーを作る必要がある。このとき局所変数の値が代入によって変更されてしまうと、内部クラス内の変数のコピーは値が変わらず、意味的に変なことになってしまう。
このため、内部クラスから参照されるメソッドの局所変数は、代入によって値を変更してはいけないこと になっている。（なお、フィールドの場合にはこのような制限は存在しない。）
例題 4.14.1 匿名クラスからメソッドの局所変数を参照する。
ファイル FinalExample.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class FinalExample extends JPanel {6private static final Color[] colors = {Color.RED, Co
7
private int c = 0;89public FinalExample() {10
setPreferredSize(new Dimension(200, 70));
11
JButton button = new JButton("Push");12
button.setForeground(colors[c]);13
button.addActionListener(new ActionListener() {14
public void actionPerformed(ActionEvent e) {15
c = (c + 1) % colors.length;
16
button.setForeground(colors[c]);
17
}
18
});
19
setLayout(new FlowLayout());
20
add(button);
21
}
22
23
public static void main(String[] args) { /* 省略 */24 }この例では buttonという局所変数が匿名クラスから参照されている。 (これに対して c や colors はフィールドである。) そのため、button = null; のよ
うにあとで button に別の値を代入しようとするとエラーになる。 なお、代入によって変更されないことを明示的にするため、変数の宣言に final という修飾子を付けることがある。例えば、上の例の場合、次のように宣言する。
1 final JButton button= new JButton("Push");Java 7 以前では、内部クラスから参照されるメソッドの局所変数は、final と宣言されている必要があったが、 Java 8 から “実質的に” final であれば（つまり、final をつけてもエラーにならないならば）良いことになった。
なお、内部クラスから参照されるという理由以外にも final と宣言することがある。代入によって値が変わることがないことが保証されるので、意味が追いやすくなるし、効率上有利になることもある。

オブジェクト指向言語 第 4 章 p.24

上の例では colors はクラスフィールドなので、final と宣言しなくても、内部クラスから参照することはできる。しかし、代入しないことがわかっている
ので final と宣言している。
Q 4.14.2 Factorial.java （例題 4.5.3）を匿名クラスを用いて書き換える。空欄を埋めて、プログラムを完成させよ．
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 public class Factorial{
6@Override7
public Factorial() {8
setPreferredSize(new Dimension(300, 50));
9
JTextField input = new JTextField("0", 8);
10JLabel output = new JLabel("
1");
11
input.addActionListener({
12
public void actionPerformed(ActionEvent e) {13// actionPerformed の中身は同じなので省略
14
}
15
});
16
setLayout(new FlowLayout());
17add(input); add(new JLabel("の階乗は"));18
add(output); add(new JLabel("です。"));
19
}
20
21
// factorial, main の定義は同じなので省略
22 }問 4.14.3 MouseTest.java, KeyTest.java を匿名クラスを用いて書き換えよ。

4.15 ラムダ式
Java 8 からは、ActionListener のようにメソッドを一つしか持たないインタ
フェースを実装する匿名クラスのオブジェクトに対して、ラムダ式 (lambda
expression, λ expression) というメソッド名も省略する書き方ができるようになった。（MouseListener や KeyListener はメソッドを 2 つ以上持つので、ラムダ式では書けない。）
例題 4.15.1 例えば、LeftRightButton.java をラムダ式を用いて書き換えると次のようになる。
ファイル LeftRightButton4.java
1 import javax.swing.*;
2 import java.awt.*;3
4 public class LeftRightButton4 extends JPanel {5private int x = 20;
67public LeftRightButton4() {8
setPreferredSize(new Dimension(200, 70));
9JButton lBtn = new JButton("Left");
10
JButton rBtn = new JButton("Right");
11lBtn.addActionListener(e -> {12
x -= 10;

オブジェクト指向言語 第 4 章 p.25

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 }

}

repaint();});
rBtn.addActionListener(e -> {x += 10;
repaint();});
setLayout(new FlowLayout());
add(lBtn); add(rBtn);@Override
public void paintComponent(Graphics g) {super.paintComponent(g);g.drawString("HELLO WORLD!", x, 55);}
public static void main(String[] args) { /* 省略 */ラムダ式は匿名クラスの（一つしかない）メソッド定義部分だけを抜き出し、さらにメソッド名も省略したものである。引数のリストと関数本体を -> でつな
ぐかたちになる。
(型 1 変数 1, 型 2 変数 2, …, 型 n 変数 n) -> { 文のならび }通常は、引数の型は省略できる。
(変数 1, 変数 2, …, 変数 n) -> { 文のならび }さらに、引数が一つの場合は、丸括弧も省略できる。
変数 -> { 文のならび }またブレースの中の文のならびが、式文が一つだけ、または return 文一つだ
けのときは、ブレース（{ と }）と return、セミコロン (;) も省略することができる。この場合、それぞれ次のような形になる。
(型 1 変数 1, 型 2 変数 2, …, 型 n 変数 n) -> 式
(変数 1, 変数 2, …, 変数 n) -> 式
変数 -> 式
Q 4.15.2 例 4.14 の FinalExample.java をラムダ式を用いて書き換えよ。
1 button.addActionListener(
2
3
4 );問 4.15.3 § 4.11 の問 4.11.2 の摂氏と華氏の変換 GUI アプリケーションをラムダ式を使って書け。

オブジェクト指向言語 第 4 章 p.26

4.16 章末問題
問 4.16.1 JTextArea, JCheckBox, JComboBox, JList, JTable, JTree な
ど、他の GUI 部品の使用法を調べよ。またこれらのクラスの部品を使ってプログラムを作れ。
問 4.16.2 これまで紹介したプログラムは、FlowLayout を用いていて、GUI 部
品がどのように配置されるかについては無関心だった。部品を自分の好みの位置に配置する方法（〜Layout という名前のクラス）を調べよ。
キーワード
イベント、イベントハンドラー、keyTypedメソッド, mouseClickedメソッド,
actionPerformedメソッド, インタフェース (interface), MouseListener
インタフェース, KeyListenerインタフェース, ActionListenerインタフェース, this, MouseEventクラス, KeyEventクラス, ActionEventクラス,
getContentPaneメソッド, addメソッド, JButtonクラス, JLabelクラス,
JTextFieldクラス, Integer.parseIntメソッド, splitメソッド, 総称クラス, ArrayListクラス, HashMapクラス, LinkedListクラス, ArrayDequeクラス、内部クラス、匿名クラス、ラムダ式、

オブジェクト指向言語 第 4 章 p.27