JShellで始めるJava入門 - Javaの世界を覗いてみる

JShellでJavaを始めてみましょう。

## 目的

プログラム未経験者が、Javaプログラミングで出てくるいろいろな概念をなんとなく把握する。

※ この記事をベースに書籍化した「[プロになるJava](https://amzn.to/3tCxpG2)」が刊行されています。

## 環境設定

まずは環境設定からです。
こちらからJDKをダウンロードします。
http://jdk.java.net/18/

コマンドラインに不慣れな人は、Adoptiumでインストーラ付のパッケージを使うといいと思います。17LTSでも構いません。
https://adoptium.net/
MacやLinuxの人は、tar.gzをダウンロードして

```
$ tar xf openjdk-18_mac-x64_bin.tar.gz
```

としてもいいと思います。Windowsではzipをダウンロードして適切なフォルダに解凍してください。

## JShellを起動する

ではJShellを起動してみます。
Windowsの人は「コマンドプロンプト」、MacやLinuxの人は「ターミナル」を開いてください。

```
$ jshell
```
で起動したらラッキー

ちなみに、`$ jshell`というのは、こういったコマンドラインで`jshell`と入力して[enter]キーを押してくださいね、という記法です。

起動しなかったら、Windowsの場合は`"\Program files\Eclipse Adoptium\jdk-18-hotspot\bin\jshell"`を起動します。`\Prog`くらいを入力して[tab]を押すと補完してくれると思います。
※ Windowsの場合、バックスラッシュ`\`は￥で入力してください
Macの場合は`/Library/Java/jdk-18/Contents/Home/bin/jshell`あたりに。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228058/39da6f93-acc9-a8f1-ebd7-123349be2c35.png)

試しに`12+23`を入力して[enter]キーを押してください。
`35`という結果が現れましたね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228058/8e077bce-fd57-3141-ad2c-e76d0da31f38.png)

JShellに何かを入力して[enter]キーを押すと、その入力をJShellがJavaのコードだと解釈して実行してくれます。今回入力したのは単なる計算ですが、これもJavaのプログラムの一部になります。
ということで、初めてのJavaプログラムは`12+23`ということになりました。やったね！

以降、jshellへの入力とその結果を次のように表します。

```
jshell> 12 + 23
$1 ==> 35
```
これはJShellに`12+23`を入力して[enter]キーを押してくださいね、そうすると`35`が表示されますよ、ということです。`$1 ==>`の部分はとりあえず無視しましょう。

## 値を扱う

### 演算

先ほどは足し算を行いました。では引き算はどうでしょう？`4-3`を試してみます。

```
jshell> 4 - 3
$2 ==> 1
```

掛け算は`*`, 割り算は`/`を使います。また、`%`で割り算の余りを計算できます。

```
jshell> 8 * 2
$3 ==> 16

jshell> 8 / 2
$4 ==> 4

jshell> 7 % 5
$5 ==> 2
```

`3+4*2`はどうでしょう？

```
jshell> 3 + 4 * 2
$6 ==> 11
```
掛け算が先に計算されていますね。`3+4`をカッコでくくれば、足し算を先に計算します。

```
jshell> (3 + 4) * 2
$7 ==> 14
```

### いろいろな型

ところで、`22/7`はどうなるでしょうか？

```
jshell> 22 / 7
$8 ==> 3
```
整数として計算されていますね。小数点以下の結果が欲しいとき、つまり実数として計算したい場合には`22.0/7`とします。

```
jshell> 22.0 / 7
$9 ==> 3.142857142857143
```
小数点を付けると、実数として扱われます。また演算のどちらかの項が実数であれば、実数として計算を行います。このように、Javaでは整数と実数を区別して計算します。

### 文字列とメソッド

ここまで数値を扱ってきました。プログラムでは単語や文章など一連の文字を扱うことも多くあります。こういった一連の文字のことをプログラムの世界では文字列と呼びます。Javaでは`"`(ダブルクォート)で囲って文字列を表します。

```
jshell> "aaa"
$10 ==> "aaa"
```

#### メソッド
文字列に対しては、いろいろな操作がしたくなります。例えば文字列を大文字に変えてみましょう。`"test".toUpperCase()`と入力してみます。`toU`まで入力して[Tab]キーを入力すると、続きを入力してくれると思います。こういった機能を「補完」といいます。

```
jshell> "test".toUpperCase()
$12 ==> "TEST"
```
"TEST"がとれましたね。
この`length()`をメソッドといいます。文字列には、このようなメソッドがたくさん用意されていて、文字列に対する操作を行います。
`"test".`で[Tab]キーを押すと、文字列に対して呼び出せるメソッドの一覧が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228058/fa7bb89f-3cf6-ba8c-1825-0881a52ffe4f.png)


メソッド|用途
---|---
length()|文字列の長さを取得
repeat(n)|文字列をn回繰り返す
replace(old, new)|文字列中のoldをnewに置き換える
charAt(index)|index番目の文字を取り出す
substring(begin, end)|文字列のbegin番目からend番目の手前までを抜き出す
toUpperCase()|文字列を大文字にする
toLowerCase()|文字列を小文字にする


では、他のメソッドも使ってみましょう。`"test".repeat(3)`を実行してみましょう。

```
jshell> "test".repeat(3)
$13 ==> "testtesttest"
```
`test`が3回繰り返した文字列が表示されましたね。`repeat`メソッドは、文字列を指定した回数繰り返すメソッドです。このように、メソッドには何か指定することが必要なときがあります。このような、メソッドに対して指定する値を「引数(ひきすう)」といいます。

`charAt`メソッドでは、指定した場所の文字を取り出すことができます。

```
jshell> "test".charAt(2)
$13 ==> 's'
```
ここで、先頭の文字が0番目であることに注意が必要です。プログラムではほとんどの場合に0が先頭で1が2番目の要素を示します。

もうひとつ、`replace`メソッドを使ってみましょう。`"test".replace("st","")`を実行してみます。

```
jshell> "test".replace("st","")
$14 ==> "te"
```
`replace`メソッドは文字列を置き換えるメソッドで、置き換え前の文字列と置き換え後の文字列を引数に取ります。このように2つ以上の引数をとる場合は`,`で引数を区切ります。`""`は空文字列といいます。`"st"`を`""`に置き換えることで、文字列から`"st"`を省いたわけですね。

メソッド呼び出しを連結させることもできます。

```
jshell> "test".repeat(3).replace("st","")
$15 ==> "tetete"
```

`"test"`が3回繰り返されて`"testtesttest"`になり、`"st"`が省かれて`"tetete"`になっています。

練習：`repeat`メソッドを使って`"hi"`を4回繰り返した文字列を作成しましょう
練習：`replace`メソッドを使って`"grape"`の`p`を`d`に置き換えた文字列を作成しましょう
練習：`toLowerCase`メソッドを使って`"HELLO"`を小文字にしてみましょう
練習：`substring`メソッドを使って`"minute"`の1番目(日常会話的には2番目)から3文字抜き出した文字列を作成しましょう

文字列の連結は`+`演算子を使います。

```
jshell> "te" + "st"
$11 ==> "test"
```

引き算はどうなるでしょうか？`"test"-"st"`で`"te"`が得れれば便利ですね。

```
jshell> "test" - "st"
|  エラー:
|  二項演算子'-'のオペランド型が不正です
|    最初の型: java.lang.String
|    2番目の型: java.lang.String
|  "test" - "st"
|  ^-----------^
```

エラーが出ました。ここでオペランドというのは、演算子の項のことです。`-`演算子には文字列は使えないということを言っています。こういうエラーメッセージもちゃんと読めるようになったほうがいいですが、今の時点では`-`演算子に文字列は使えないんだなーくらいの認識で大丈夫です。
文字列に対しては演算子として`+`演算子だけが使えます。

#### JShellの操作

基本的な操作として、上キーを押すと前に入力したものが出てきます。前に入力したものをもう一度実行したい場合に使えます。

JShellを終了させるには`/exit`コマンドを使います。

```
jshell> /exit
|  終了します

$
```

JShellでは、[Enter]キーが押されたときにキリのいいところまで入力されていると判断できれば、その式を実行します。しかし、途中で改行してしまった場合やカッコが足りなかった場合など、中途半端に行が終わった場合は、次のように続きの入力を求められます。

```
jshell> "test".repeat(
   ...>
```
長い行を入力するときに自分で改行したときはいいのですが、ちゃんと１行入力したつもりなのにどこかでカッコが足りなくて行が終わっていないときには、間違い探しが面倒で、改めて入力したほうが早いときもあります。そういうときは[Ctrl]+[c]でキャンセルできます。



### 変数

ところでこの値、円周率に近いので円周率の代わりにいろいろ使いたいとします。これは古代バビロニアで円周率として使われていたようです。けれどもいちいち`22.0/7`と入力するのは面倒ですね。

そこで見直してみると`22.0 / 7`を計算したところで次のような表示になっていました。

```
jshell> 22.0 / 7
$9 ==> 3.142857142857143
```

$9という名前で値が使えることを示しています。

```
jshell> $9
$9 ==> 3.142857142857143
```

けれども、この数字を覚えておくのは面倒です。値が１つだけならいいのですが、覚えておきたい値はどんどん増えていきます。もっと覚えやすくて意味がわかりやすい名前を値に対してつけれると便利です。
そこで変数ですよ。
変数は`var 変数名=値`とすることで定義できます。

```
jshell> var pi = 22.0 / 7
pi ==> 3.142857142857143
```
これで`pi`という変数が定義されて`3.142857142857143`という値が割り当てられました。`pi`とだけ入力してみると、割り当てられた値が表示されます。

```
jshell> pi
pi ==> 3.142857142857143
```

これを使って、半径5の円の円周の長さを求めてみます。円周の長さは直径x円周率でしたね。変数は、値として演算に使うことができます。

```
jshell> 5*2*pi
$16 ==> 31.428571428571427
```

面積は半径x半径x円周率でしたね。

```
jshell> 5*5*pi
$17 ==> 78.57142857142857
```

このように、変数を使って値を使いまわすことができました。
ところで、`$17`の位置には変数piを定義したときには`pi`と表示されていましたね。つまり、これは`$17`という変数に`78.57142857142857`を割り当てましたよ、ということを表しています。

```
jshell> $17
$17 ==> 78.57142857142857
```

ところで、実際にはJavaでは`Math.PI`で精度の高い円周率が保持されています。

```
jshell> Math.PI
$82 ==> 3.141592653589793
```
`Math`クラスの`PI`フィールド、ということになりますが、詳しくはまた別に勉強しましょう。

円周率としてこの値を使うと、半径5の円の面積は次のようになります。

```
jshell> 5*5*Math.PI
$81 ==> 78.53981633974483
```

変数`pi`に、この`Math.PI`を割り当てておきましょう。

```
jshell> pi=Math.PI
pi ==> 3.141592653589793
```
このように、変数には値を割り当てなおすこともできます。
改めて`5*5*pi`を計算してみると、次のように`Math.PI`を使った場合と同じ結果がでました。

```
jshell> 5*5*pi
$84 ==> 78.53981633974483
```

### 変数の型

先ほどの変数`pi`に文字列を割り当ててみましょう。

```
jshell> pi="circle ratio"
|  エラー:
|  不適合な型: java.lang.Stringをdoubleに変換できません:
|  pi="circle ratio"
|     ^------------^
```
エラーが出ました。`Stringをdoubleに変換できません`と言われていますね。
Javaの変数では、その変数がどのような種類の値を割り当てれるかが決まっています。そのような、値の種類のことを「型」といいます。言い換えると、変数は型が決まっているということですね。
ここまで出てきたものでは整数が`int`、実数が`double`、文字列が`String`になっています。
では、変数の型を確認してみましょう。JShellでは`/var`コマンドで変数の型を確認できます。

```
jshell> /var pi
|    double pi = 3.141592653589793
```
これは、変数`pi`の型が`double`であり`3.141592653589793`という値が割り当てられていることを表します。`double`が実数を扱う型です。

文字列の場合を見てみましょう。まず文字列`"circle"`を割り当てた変数`str`を用意します。

```
jshell> var str="circle"
str ==> "circle"
```

`/var`コマンドで型を確認してみましょう。

```
jshell> /var str
|    String str = "circle"
```

`String`という型になっています。文字列は`String`型で表されるわけですね。
実数を割り当てようとするとエラーになります。

```
jshell> str=3.14
|  エラー:
|  不適合な型: doubleをjava.lang.Stringに変換できません:
|  str=3.14
|      ^--
```

ここまで`var`を使って変数を用意していました。`var`を使うと自動的に変数の型を決めてくれます。ここで、`型`を指定して変数を用意することもできます。

```
jshell> String message="hello"
message ==> "hello"
```

また、このような変数に対してメソッドを呼び出すこともできます。

```
jshell> message.length()
$325 ==> 5
```
メソッドは、型によって呼び出せるものが決まっています。`length`メソッドや`repeat`メソッドは、`String`型に準備されたメソッドです。`double`型には呼び出せるメソッドはありません。

メソッドから返ってきた値を変数に割り当てることもできます。

```
jshell> var count=message.length()
count ==> 5
```

ここで変数`count`は`int`という型になっています。

```
jshell> /var count
|    int count = 5
```
`int`型は整数を扱う型です。

練習:`var`を使って、実数`1.414`を割り当てた変数`root2`を用意してみましょう。
練習:`var`を使わず、文字列"apple"を割り当てた変数`word`を用意してみましょう。
練習:上で用意した`word`に対して`toUpperCase`メソッドを呼び出してみましょう。

### メソッドの定義
変数を使って値を使いまわすことができましたが、半径x半径x円周率のような式を使いまわすことができると便利です。
Javaではメソッドを定義することで式を使いまわすことができます。

ちょっと長いですが、`double menseki(double r){return r*r*pi;}`を実行してみてください。

```
jshell> double menseki(double r){return r*r*pi;}
|  次を作成しました: メソッド menseki(double)
```
これで`menseki`メソッドが定義されました。次のようにして使えます。

```
jshell> menseki(5)
$34 ==> 78.53981633974483

jshell> menseki(3)
$33 ==> 28.274333882308138
```
これで式を使いまわすことができますね。

それではメソッドの定義を少し詳しく見ておきましょう。メソッドの定義を適当に改行すると次のようになります。

```
double menseki(double r) {
  return r*r*pi;
}
```
この定義は次のようになっています。

```
結果の型 メソッド名(引数の型 引数を扱う変数) {
  return 式;
}
```

今回は、実数を受け取って実数を返す`menseki`という名前のメソッドを定義したことになります。受け取った引数を`r`で受け取るようにしています。radius(半径)のrです。
値を返すときには`return`文を使います。ここで、受け取った半径を2回掛けて円周率を掛けたものを返しています。

次のように、JShellの中で改行をして定義することもできます。

```
jshell> double menseki(double r) {
   ...>   return r*r*pi;
   ...> }
|  次を変更しました: メソッド menseki(double)
```
練習：引数の名前は`r`である必要はありません。menseki2として、引数をaで受け取るように同じ機能のメソッドを定義してみてください。
練習：半径を受け取って円周の長さを返すメソッドを定義してみてください。

## Swing

なんか文字ばっかりでつまらん、ってなりませんでしたか？ということで文字ばっかりじゃないものを実行してみましょう。
ウィンドウを表示します。Javaでは、標準でSwingというGUIツールキットが用意されています。GUIツールキットというのは、ウィンドウを表示したりボタンを配置したりする部品群のことです。

### ウィンドウを表示
まずはウィンドウを用意します。

```
jshell> var f = new javax.swing.JFrame("test")
f ==> javax.swing.JFrame[fram ... bled=true]
```

ちょっとよくわかりませんが、変数fになんらかが割り当てられました。
これに対して`show()`メソッドを呼び出してみます。

```
jshell> f.show()
```

左上に何か表示されました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/4369d192-6b68-7db9-db60-472e4822b884.png)
小さいので、サイズを大きくしてみます。サイズを決めるには`setSize`メソッドを使います。ここで横サイズと縦サイズと指定します。

```
jshell> f.setSize(400,300)
```
大きくなった！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/fe075095-1675-8d10-c6a3-e588aea4d7eb.png)

#### クラスとオブジェクト

ウィンドウを用意するとき
`var f = new javax.swing.JFrame("test")`
を実行しました。
Javaでは、ウィンドウやボタンなどプログラムで扱う対象を「オブジェクト」として用意します。ここでは変数`f`にはウィンドウのオブジェクトが割り当てられています。Swingではウィンドウは`javax.swing.JFrame`という型で表します。オブジェクトはなんらかの型を基にしてして生成されます。オブジェクトの基になるような型を「クラス」と呼びます。`javax.swing.JFrame`はクラスということになります。
クラスからオブジェクトを生成するときには`new`演算子を使って`new クラス(引数)`のようにして生成します。引数はクラスによって決まっています。
見方によっては、オブジェクトを生成するときは`new`演算子と共に特別なメソッドを呼び出しているようにも見えます。このように見たとき、このメソッドのことを「コンストラクタ」と呼びます。コンストラクタは、クラスと同じ名前で呼び出しに`new`演算子が必要なメソッドだと言えます。

#### JavaDoc
この`javax.swing.JFrame`のドキュメントはここにあります。
https://docs.oracle.com/en/java/javase/18/docs/api/java.desktop/javax/swing/JFrame.html

英語ですね。日本語がいいという場合はこちらを。
https://docs.oracle.com/javase/jp/17/docs/api/java.desktop/javax/swing/JFrame.html

このドキュメントの形式を「JavaDoc」といいます。JavaのAPIのドキュメントは、だいたいこの形式になっています。

「javadoc JFrame」など、javadoc+クラス名でぐぐると、だいたいJavaDocが出てきます。

例えば今回つかったコンストラクタは次のような説明になっています。
![スクリーンショット 2018-06-11 19.54.59.png](https://qiita-image-store.s3.amazonaws.com/0/228058/db49b4d0-22bd-3d88-15cb-62c6f1d06b31.png)

これを見ると、今回使ったのは`JFrame​(String title)`というコンストラクタだったことがわかります。引数のないコンストラクタも用意されているので、タイトルを指定せずにウィンドウを生成できることもわかります。
こういったことはもう少しJavaの言語を勉強しないとわからないかもしれませんが、JavaDocを確認することで今かいたことが何なのかがわかってJavaの言語の理解につながるということもあります。
また一般に、解説書で全てを解説するということはないので、このような一次情報を参照して正確に把握するというのも大事になります。

練習：いままで使ったStringのreplaceメソッドをJavaDocで調べてみましょう
ヒント：右上の検索ボックスで検索すると便利です。

### パッケージとimport

ウィンドウが表示できたので、テキストエリアを配置してみましょう。テキストエリアは複数行の文字列が入力できる部品です。Swingではテキストエリアは`javax.swing.JTextArea`クラスで扱います。またこのようにウィンドウに配置する部品を「コンポーネント」と呼びます。
テキストエリアを配置するために、まずはテキストエリアのオブジェクトを生成する必要があります。オブジェクトを生成するには、クラス名と同じ名前のメソッド、つまりコンストラクタに`new`演算子を付けて呼び出すんでしたね。しかし`javax.swing.JTextArea`というのは長くていちいち入力するのは面倒です。
実際には`javax.swing.JTextArea`は二つの部分に別れていて、最後の区切りだけがクラス名、その前はパッケージ名となっています。つまり`javax.swing`というパッケージの`JTextArea`クラスを表しています。「パッケージ」はJavaのクラスを分類する仕組みです。

そこで、`import`文を使うと、パッケージ名を省略できるようになります。`import javax.swing.*`とすると、`javax.swing`パッケージのクラスはパッケージ名を省略してクラス名だけで表すことができるようになります。

```
jshell> import javax.swing.*
```

いままで無視していたのですが、`String`型が`java.lang.String`というふうに表示されることがありました。`String`型は`java.lang`パッケージに入っていて、`java.lang`パッケージはあらかじめ`import`が行われているためにパッケージ名を省略できていました。

それでは、テキストエリアを表す`JTextArea`クラスのオブジェクトを生成してみましょう。

```
jshell> var textarea = new JTextArea()
textarea ==> javax.swing.JTextArea[,0,0,0x0,i ... rap=false]
```

これをウィンドウに配置する必要があります。ウィンドウを表す`JFrame`オブジェクトに対して`add`メソッドを呼び出すことでウィンドウに追加できます。

```
jshell> f.add(textarea)
$14 ==> javax.swing.JTextArea[,0,0,0x0,inval ... se,wrap=false]
```

ただ、このままではウィンドウに表示されないので、ウィンドウを再編成してもらう必要があります。ウィンドウのサイズを変えると再編成が行われるので、ウィンドウの端をドラッグしてサイズを変えるか、`setSize`メソッドを呼び出すかしてみます。`setSize`メソッドでサイズを指定するときにウィンドウサイズが変更されない場合は何も行われないので、少しサイズを変えておく必要があります。

```
jshell> f.setSize(400,301)
```
テキストエリアが表示されて、文字が入力できるようになりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/519337ff-0649-8c62-9f5d-6cca77e73072.png)

テキストエリアに対して、appendメソッドで文字列を追加することができます。

```
jshell> textarea.append("te")

jshell> textarea.append("st")
```
ただし、そのままだと改行されずに続けて追加されてしまいます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/beccb2e7-9d9f-d740-2951-d4b7ac9cd790.png)

改行は`\n`で表します。(Windowsの場合`￥n`です)

```
jshell> textarea.append("\ntester\n")
```
ちゃんと改行されましたね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/cdadcb22-68c6-f64a-af19-520ea331ca23.png)

### ボタンの追加

さて、それでは、ボタンを追加してみましょう。Swingではボタンは`JButton`クラスで扱います。コンストラクタの引数にボタンのラベル文字列を指定することができます。

```
jshell> var button = new JButton("Hello")
button ==> javax.swing.JButton[,0,0,0x0,inval...pable=true]
```

これをウィンドウに追加したいのですが、すでにテキストエリアを配置しているので、重ならない位置に追加する必要があります。
JFrameでは、東西南北と真ん中という指定でコンポーネントを配置します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/d6850966-da10-aaa4-005c-39eb1ae48c94.png)

`add`メソッドの第一引数に配置する場所、第二引数に配置するコンポーネントを指定します。

```
jshell> f.add("North", button)
$27 ==> javax.swing.JButton[,0,0,0x0,inval...ltCapable=true]
```

`North`をスペルミスなどすると、このようなエラーが出ます。大文字小文字も区別するので気をつけてください。

```
jshell> f.add("Nort", button)
|  Exception java.lang.IllegalArgumentException: cannot add to layout: unknown constraint: Nort
|        at BorderLayout.addLayoutComponent (BorderLayout.java:468)
|        at BorderLayout.addLayoutComponent (BorderLayout.java:429)
|        at JRootPane$1.addLayoutComponent (JRootPane.java:507)
|        at Container.addImpl (Container.java:1151)
|        at Container.add (Container.java:1028)
|        at JFrame.addImpl (JFrame.java:553)
|        at Container.add (Container.java:459)
|        at (#31:1)
```

ところでこのエラーはだいぶ前に変数piに文字列を割り当てようとしたときと違います。
`add`をスペルミスしたときとも違いますね。

```
jshell> f.ad("North", b)
|  エラー:
|  シンボルを見つけられません
|    シンボル:   メソッド ad(java.lang.String,javax.swing.JButton)
|    場所: タイプjavax.swing.JFrameの変数 f
|  f.ad("North", b)
|  ^--^
```

これらのエラーは発生するタイミングが違っていて、addや変数piに文字列を割り当てようとしたときのエラーはプログラムを解釈するときのエラー、"North"を間違えたときのエラーは解釈された処理を実行するときのエラーです。
プログラムを解釈するときのエラーをコンパイルエラー、実行時のエラーを例外といいます。
いまはどちらも命令を打ち込んでenterを押したときに発生するので区別がわかりにくいですが、実際の開発時には明確にわかると思います。とりあえず今は、エラーには2種類あるんだなと感じてもらえれば大丈夫です。

さて、addがうまく実行できたとしても、まだボタンが表示されていません。
`setSize`メソッドでウィンドウを再構成させると、ボタンが表示されます。

```
jshell> f.setSize(400,300)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/cea72122-55ba-9dbc-47d5-3b60f95d6694.png)

けれども、このボタンを押しても何も起きませんね。なにか処理を書く必要があります。次のように入力してみてください。`addActionListener`はちょっと長いですが、`addAc`まで入力して[tab]キーを押すと続きは補完されるはずです。

```
jshell> button.addActionListener(ae -> textarea.append("Hello!\n"))
```
これで、ボタンが押されたときに「Hello」と表示されるようになりました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/6d5df393-0cc4-60b0-129a-c52fae5840fb.png)

ボタンが押されたときの処理を追加するには`addActionListener`メソッドを使います。
ここで引数に`ae->textarea.append("Hello!\n")`を指定しています。`addActionListener`メソッドには「ボタンが押されたときにこの処理を呼び出してくださいね」という感じでなんらかの処理を渡す必要がありました。ここでの処理は`textarea.append("Hello!\n")`ですが、処理を値として渡すには「ラムダ式」などを使う必要があります。
ラムダ式は次のように書きます。

```
引数 -> 処理
```
ボタンを押したときの処理の場合は、引数として`ActionEvent`オブジェクトを受け取るのでここでは`ae`としていますが、わかりやすければなんでも構いません。受け取った引数は、今回は使っていません。

### テキストフィールドで入力を受け取る
もうちょっとがんばりましょうね。
ボタンを押すとテキストフィールドに入力された文字列が表示される、というのをやってみます。
テキストフィールドとボタンを追加したいのですが、JFrameのレイアウト方式ではそのままでは追加できません。そこで、`JPanel`コンポーネントを使います。

```
jshell> var panel = new JPanel()

jshell> f.add("South", panel)
```
`JPanel`コンポーネントは左から順にコンポーネントを並べるレイアウトになっていて、ここにいろいろ載せてから`JFrame`ウィンドウに追加すると、いい感じになります。ここでは`South`の位置に追加することにしました。
ウィンドウサイズを変えてみると、少し何か表示されてますね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/098966a2-3956-370f-d563-7eb80f5062ab.png)

テキストフィールドを追加します。テキストフィールドは1行だけの入力するコンポーネントで`JTextField`コンポーネントを使います。

```
jshell> var textfield = new JTextField()

jshell> textfield.setColumns(15)

jshell> panel.add(textfield)
```
`setColumns`メソッドで幅を決めています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/d520f065-0f39-5637-5870-09970045c578.png)

試しになにか入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228058/33359ac4-a4d8-af44-bc9a-a449b962942f.png)



最後にボタンを追加してみましょう。

```
jshell> var printButton = new JButton("Print")

jshell> printButton.addActionListener(ae -> textarea.append(textfield.getText() + "\n"))

jshell> panel.add(printButton)
```

ボタンを押すとテキストフィールドに入力した文字列がテキストエリアに追加されました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/b8d68901-c7b8-260c-93df-29b7472f57dc.png)

練習：`Yeah!`とテキストエリアに表示するボタンを追加してみましょう。
練習：テキストフィールドに入力された文字列のアルファベットを大文字にしてテキストエリアに出力するボタンを追加してみましょう。文字列のアルファベットを大文字にするには、`toUpperCase`メソッドを使います。先にJShell上で`toUpperCase`メソッドの使い方を試しておきましょう。

## JShellを離れてJavaのプログラムを作る
最後に、これまでJShellで試したことを、独立したJavaのプログラムとして書いてみましょう。
メモ帳やテキストエディットなどで次のソースコードを入力して、デスクトップに`FirstWindow.java`という名前で保存してください。

```java:FirstWindow.java
import javax.swing.*;

public class FirstWindow {
  public static void main(String... args) {
    var frame = new JFrame("test");

    var textarea = new JTextArea();
    frame.add(textarea);

    var textfield = new JTextField();
    textfield.setColumns(15);
    var button = new JButton("Print");
    button.addActionListener(ae -> textarea.append(textfield.getText() + "\n"));

    var panel = new JPanel();
    panel.add(textfield);
    panel.add(button);
    frame.add("North", panel);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 300);
    frame.show();
  }
}
```
いろいろJShellでは出なかったものが追加されていますね。また、JShellで入力したコマンドには`;`(セミコロン)がついています。けれども、このチュートリアルを始める前に比べたら「読める、読めるぞ！」という感じじゃないでしょうか。

では、このソースコードを動かしてみます。
コマンドプロンプトを開いてください。今回はJShellは使いません。
`cd`コマンドを使ってデスクトップに移動します。

```
$ cd Desktop
```

それから、`javac`コマンドで先ほど入力したソースコードをコンパイルします。

```
$ javac FirstWindow.java
```
エラーが出たら修正して保存してからまたコンパイルを行なってください。
エラーが出なくなったら作成されたファイルを確認してみましょう。
Windowsでは`dir`コマンド、MacやLinuxでは`ls`コマンドを使います。

```
$ dir FirstWindow.*
```
`FirstWindow.class`ファイルができていますね。これがJavaの実行コードです。これを実行するには`java`コマンドを使います。

```
$ java FirstWindow
```
ウィンドウが表示されたでしょうか？表示されれば成功です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/228058/0d221ae2-da39-c70d-f047-433b52c48e4e.png)

ここからJavaの本格的な勉強を始めてください。