
6日でできる 新Java入門|改良2:クイズゲームのためのSwing入門①
Swingを知れば、Javaのクイズゲームは「文字だけの画面」から「クリックして遊べるアプリ」へ進化する
前回までの改良では、クイズゲームの問題データをアニメクイズ用に差し替えました。
dragonball_quiz.txt、kimetsu_quiz.txt、jojo_quiz.txt を使うことで、ドラゴンボール・クイズ、鬼滅の刃・クイズ、ジョジョの奇妙な冒険・クイズを選べる形にしました。
ここまでのクイズゲームは、コマンドライン上で文字を入力して遊ぶ CUI アプリでした。
CUI は仕組みを学ぶには分かりやすいですが、ユーザーが直感的に操作するには少し物足りないところもあります。
そこで、ここからはクイズゲームを GUI 化していきます。
GUI とは、ボタン、ラベル、ウィンドウ、選択リストなどを使って、画面上で操作できる形式のことです。
たとえば、ジャンルをコンボボックスから選び、スタートボタンを押し、4つの選択肢ボタンをクリックして答えるような形です。
今回の記事では、いきなり完成版の GUI プログラムを掲載するのではなく、まず Swing の基本から確認します。
Swingとは何か、なぜ AWT ではなく Swing を使うのか、そしてクイズゲームの GUI 化で使う Swing の命令の前半部分を中心に解説していきます。
なお、完成版の QuizGame.java、QuizGenre.java、QuizManager.java は、最後の記事である「改良4:クイズゲームをGUIにする」でまとめて掲載します。
この記事では、Swing の部品や考え方を理解することを目的にします。
Swingとは
Swing は、Javaで GUI アプリケーションを作るためのライブラリです。
画面にウィンドウを表示したり、ボタンを置いたり、文字を表示したり、選択リストを作ったりできます。
Javaで GUI を作るとき、Swing を使うと次のような画面部品を扱えます。
| Swingの部品 | 役割 |
|---|---|
| JFrame | アプリのウィンドウを作る |
| JPanel | 部品をまとめるための領域を作る |
| JLabel | 文字を表示する |
| JButton | クリックできるボタンを作る |
| JComboBox | 選択リストを作る |
| JOptionPane | メッセージダイアログを表示する |
| Timer | 一定時間後に処理を実行する |
クイズゲームを GUI 化する場合、これらの部品を組み合わせて画面を作ります。
たとえば、タイトル画面では、次のような部品が必要になります。
| 画面要素 | Swingで使う部品 |
|---|---|
| アプリタイトル | JLabel |
| ジャンル選択 | JComboBox |
| スタートボタン | JButton |
| 全体のウィンドウ | JFrame |
| 部品を配置する領域 | JPanel |
CUI版では、文字を表示して、キーボードから番号を入力していました。
GUI版では、画面に部品を配置し、ユーザーがクリックした操作に応じて処理を進めていきます。
Swingで作るGUIアプリのイメージ
Swingで作るクイズゲームは、次のような流れになります。
| 画面 | 内容 |
|---|---|
| タイトル画面 | アプリ名、ジャンル選択、スタートボタンを表示する |
| クイズ画面 | 問題文と4つの選択肢ボタンを表示する |
| 結果画面 | 最終得点とタイトルへ戻るボタンを表示する |
CUI版では、上から順に文字が流れていく形でした。
一方、GUI版では画面を切り替えながら進みます。
たとえば、スタートボタンを押すと、タイトル画面からクイズ画面へ切り替わります。
選択肢ボタンを押すと、正解・不正解が表示され、少し待って次の問題へ進みます。
全問が終わると、結果画面へ切り替わります。
このように、GUI化では「処理の順番」だけでなく、「画面の状態」を考える必要があります。
AWTではなくSwingを使う理由
Javaには、Swingより前から存在する AWT という GUI 用の仕組みもあります。
AWT は Abstract Window Toolkit の略で、Java初期からあるGUIライブラリです。
では、なぜ今回のクイズゲームでは AWT ではなく Swing を使うのでしょうか。
主な理由は、Swingのほうが学習用のGUIアプリを作りやすく、画面部品も扱いやすいからです。
| 比較項目 | AWT | Swing |
|---|---|---|
| 登場時期 | Java初期からある | AWTの後に登場 |
| 部品の種類 | 基本的な部品が中心 | 豊富な部品が使える |
| 見た目 | OSに依存しやすい | Java側で見た目を制御しやすい |
| 軽量性 | OSの部品に依存する重い部品が多い | Javaで描画する軽量部品が中心 |
| 学習用途 | 基礎理解には使える | 実用的なGUI学習に向いている |
AWTでもボタンやウィンドウは作れます。
ただし、Swingには JLabel、JButton、JPanel、JComboBox、JOptionPane など、学習用にも実用的にも使いやすい部品がそろっています。
今回のクイズゲームでは、タイトル画面、クイズ画面、結果画面を切り替えながら表示します。
さらに、ジャンル選択、選択肢ボタン、結果表示など、複数の画面部品を組み合わせます。
そのため、Swingを使うほうが自然です。
SwingとAWTの関係
SwingとAWTは完全に別物ではありません。
Swingの画面作成では、AWTのクラスも一緒に使います。
たとえば、GUI化したクイズゲームでは、次のような import が使われます。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;ここで、javax.swing は Swing の部品を使うためのパッケージです。
一方、java.awt はレイアウト、色、フォント、サイズなどに関係する部品を使うために利用します。
| import | 主な役割 |
|---|---|
| javax.swing.* | JFrame、JPanel、JLabel、JButton などを使う |
| java.awt.* | BorderLayout、CardLayout、Color、Font などを使う |
| java.awt.event.* | ボタンを押したときのイベント処理を使う |
つまり、GUI画面の部品は Swing、配置や見た目の一部は AWT、クリック処理は event 系のクラス、という形で組み合わせます。
クイズゲームで使うSwingの前半部分
ここからは、GUI化したクイズゲームで使う Swing 関連の命令を見ていきます。
この記事では前半として、主に画面の土台作りと、タイトル画面で使う部品を中心に解説します。
今回扱う主な内容は次のとおりです。
| 分類 | 扱う内容 |
|---|---|
| ウィンドウ作成 | JFrame |
| 画面の土台 | JPanel |
| 画面切り替え | CardLayout |
| 文字表示 | JLabel |
| 選択リスト | JComboBox |
| ボタン | JButton |
| 配置 | BorderLayout、BoxLayout |
| 見た目 | Font、Color、Dimension、BorderFactory |
完成版プログラムそのものはこの記事では掲載しませんが、どの部品がどんな役割を持つのかを先に理解しておくと、後の記事でプログラム全体を見たときにかなり読みやすくなります。
JFrame:アプリのウィンドウを作る
Swingアプリの基本になるのが JFrame です。
JFrame は、アプリケーションのウィンドウそのものを表します。
クイズゲームでいうと、タイトル画面、クイズ画面、結果画面はすべて1つのウィンドウの中に表示されます。
そのウィンドウの土台になるのが JFrame です。
| JFrameで行うこと | 内容 |
|---|---|
| タイトルを設定する | ウィンドウ上部に表示する名前を決める |
| 閉じる動作を設定する | ×ボタンを押したときに終了するようにする |
| サイズを設定する | 画面の幅と高さを決める |
| 表示位置を設定する | 画面中央に表示する |
| パネルを追加する | 中身の画面を配置する |
代表的な設定は次のようなものです。
setTitle("アニメクイズゲーム");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(760, 520);
setLocationRelativeTo(null);それぞれの意味を整理します。
| 命令 | 内容 |
|---|---|
| setTitle | ウィンドウのタイトルを設定する |
| setDefaultCloseOperation | 閉じるボタンを押したときの動作を設定する |
| setSize | ウィンドウサイズを設定する |
| setLocationRelativeTo(null) | ウィンドウを画面中央に表示する |
CUI版では、コマンドプロンプトやターミナルに文字を表示していました。
GUI版では、まず JFrame でアプリ専用のウィンドウを作るところから始まります。
JPanel:部品を配置するための土台
JPanel は、ボタンやラベルなどの部品をまとめて置くための領域です。
JFrame が家全体だとすると、JPanel は部屋のようなものです。
クイズゲームでは、次のようなパネルを作ります。
| パネル | 役割 |
|---|---|
| タイトル画面用パネル | タイトル、ジャンル選択、スタートボタンを置く |
| クイズ画面用パネル | 問題文、選択肢ボタン、結果メッセージを置く |
| 結果画面用パネル | 得点とタイトルへ戻るボタンを置く |
JPanel を使うことで、画面ごとに部品を整理できます。
たとえば、タイトル画面にはタイトル画面用の JPanel、クイズ画面にはクイズ画面用の JPanel を作ります。
それらをあとで CardLayout で切り替えることで、1つのウィンドウの中で画面遷移を表現できます。
CardLayout:画面をカードのように切り替える
GUI版クイズゲームでは、タイトル画面、クイズ画面、結果画面を切り替えます。
この画面切り替えに使うのが CardLayout です。
CardLayout は、複数の画面をカードのように重ねておき、必要なカードだけを表示するレイアウトです。
| 画面名 | 内容 |
|---|---|
| TITLE | タイトル画面 |
| QUIZ | クイズ画面 |
| RESULT | 結果画面 |
イメージとしては、3枚のカードを重ねておき、場面に応じて前面に出すカードを変える形です。
cardLayout = new CardLayout();
mainPanel = new JPanel(cardLayout);このように、CardLayout を使う JPanel を用意します。
そこにタイトル画面、クイズ画面、結果画面を追加します。
mainPanel.add(createTitlePanel(), "TITLE");
mainPanel.add(createQuizPanel(), "QUIZ");
mainPanel.add(createResultPanel(), "RESULT");そして、表示したい画面を次のように切り替えます。
cardLayout.show(mainPanel, "TITLE");
cardLayout.show(mainPanel, "QUIZ");
cardLayout.show(mainPanel, "RESULT");| 命令 | 表示される画面 |
|---|---|
| cardLayout.show(mainPanel, "TITLE") | タイトル画面 |
| cardLayout.show(mainPanel, "QUIZ") | クイズ画面 |
| cardLayout.show(mainPanel, "RESULT") | 結果画面 |
クイズゲームのように、画面の状態が段階的に変わるアプリでは、CardLayout がとても使いやすいです。
JLabel:文字を表示する部品
JLabel は、画面上に文字を表示するための部品です。
クイズゲームでは、タイトル、説明文、問題文、結果メッセージ、スコア表示などに使います。
| 使用場所 | 表示内容 |
|---|---|
| タイトル画面 | アニメクイズゲーム |
| タイトル画面 | ジャンルを選んでスタートを押してください |
| クイズ画面 | クイズタイトル |
| クイズ画面 | 問題文 |
| クイズ画面 | 正解・不正解メッセージ |
| 結果画面 | 最終スコア |
JLabel は文字を表示するだけの部品なので、ユーザーがクリックして操作するものではありません。
ただし、フォントや配置を調整することで、画面の印象を大きく変えられます。
たとえば、タイトルは大きく太字にします。
JLabel titleLabel = new JLabel("アニメクイズゲーム", SwingConstants.CENTER);
titleLabel.setFont(new Font("Meiryo", Font.BOLD, 38));ここで使われている SwingConstants.CENTER は、文字を中央揃えにする指定です。
| 命令 | 内容 |
|---|---|
| new JLabel | ラベルを作る |
| SwingConstants.CENTER | 中央揃えにする |
| setFont | 文字の種類、大きさ、太さを設定する |
クイズゲームでは、問題文も JLabel で表示します。
問題文は長くなることがあるため、HTML形式を使って中央寄せ表示する工夫もできます。
JButton:クリックできるボタン
JButton は、ユーザーがクリックできるボタンです。
クイズゲームでは、スタートボタン、選択肢ボタン、タイトルへ戻るボタンなどに使います。
| ボタン | 役割 |
|---|---|
| スタート | ジャンルを決めてゲームを開始する |
| 選択肢1~4 | 回答として選ぶ |
| タイトルへ | 結果画面からタイトル画面へ戻る |
ボタンは、ただ画面に置くだけでは意味がありません。
クリックされたときに何をするかを登録する必要があります。
そこで使うのが addActionListener です。
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
startGame();
}
});このコードは、スタートボタンが押されたら startGame() を実行する、という意味です。
| 要素 | 内容 |
|---|---|
| addActionListener | ボタンが押されたときの処理を登録する |
| ActionListener | イベントを受け取るための仕組み |
| actionPerformed | 実際にボタンが押されたときに動くメソッド |
| startGame() | ゲーム開始処理 |
CUI版では、ユーザーが番号を入力して Enter を押すことで処理が進みました。
GUI版では、ボタンをクリックすることで処理が進みます。
この「クリックされたら処理を実行する」という考え方が、GUIプログラミングの基本です。
JComboBox:選択リストを作る
JComboBox は、複数の候補から1つを選ぶための部品です。
今回のクイズゲームでは、ジャンル選択に使います。
CUI版では、次のように番号を入力してジャンルを選んでいました。
1: ドラゴンボール・クイズ
2: 鬼滅の刃・クイズ
3: ジョジョの奇妙な冒険・クイズ
==>GUI版では、JComboBox を使ってリストから選べるようにします。
genreComboBox = new JComboBox<QuizGenre>(QuizGenre.values());ここでは、QuizGenre.values() によって enum に定義されているジャンル一覧を取得し、それを JComboBox に入れています。
| 部分 | 内容 |
|---|---|
| JComboBox | QuizGenre 型の選択リスト |
| QuizGenre.values() | enum の全ジャンルを取得 |
| getSelectedItem() | 選択されたジャンルを取得 |
JComboBox に QuizGenre を入れる場合、画面に表示される文字は toString() の戻り値になります。
そのため、QuizGenre 側で toString() を定義しておくと、コンボボックスにタイトル名を表示できます。
public String toString() {
return title;
}これにより、DRAGONBALL という enum 名ではなく、ドラゴンボール・クイズ のような分かりやすい表示になります。
Font:文字の見た目を整える
Swingでは、setFont を使って文字の見た目を調整できます。
クイズゲームでは、タイトルや問題文、ボタンの文字を見やすくするために Font を使います。
new Font("Meiryo", Font.BOLD, 38)この指定は、メイリオ、太字、38px相当の大きさという意味です。
| 要素 | 内容 |
|---|---|
| Meiryo | 日本語表示に向いたフォント |
| Font.BOLD | 太字 |
| Font.PLAIN | 通常の太さ |
| 数値 | 文字サイズ |
たとえば、タイトルは大きく太字にし、説明文は少し小さめの通常文字にします。
| 表示場所 | フォント設定の考え方 |
|---|---|
| タイトル | 大きく太字 |
| 説明文 | 読みやすい通常サイズ |
| 問題文 | 目立つように太字 |
| ボタン | 押しやすく見えるサイズ |
GUIでは、同じ文字でもサイズや太さで印象が変わります。
学習用アプリでは、重要な情報を大きく、補足的な情報を少し小さくすると読みやすくなります。
Color:背景色を設定する
Swingでは、setBackground を使って背景色を設定できます。
今回のクイズゲームでは、タイトル画面や結果画面に淡い青系の背景色を使っています。
panel.setBackground(new Color(235, 245, 255));
Color には RGB の値を指定します。
RGB は、赤、緑、青の強さを数値で表す方法です。
| 指定 | 意味 |
|---|---|
| new Color(235, 245, 255) | 淡い青系の色 |
| Color.WHITE | 白 |
| setBackground | 背景色を設定する |
白と青を基調にすると、学習教材らしく、すっきりした画面にしやすいです。
Dimension:部品の大きさを指定する
Dimension は、部品の幅と高さを指定するときに使います。
たとえば、スタートボタンやジャンル選択リストの大きさを調整できます。
startButton.setPreferredSize(new Dimension(180, 50));これは、スタートボタンの希望サイズを 幅180、高さ50 にする指定です。
| 命令 | 内容 |
|---|---|
| new Dimension(180, 50) | 幅180、高さ50のサイズ情報 |
| setPreferredSize | 部品の希望サイズを設定する |
ただし、Swingではレイアウトマネージャが最終的な配置やサイズを調整します。
そのため、setPreferredSize は「このくらいの大きさにしたい」という希望を伝えるものだと考えると分かりやすいです。
BorderFactory:余白を作る
画面を見やすくするには、部品同士の間隔や余白が大切です。
Swingでは、BorderFactory.createEmptyBorder を使って余白を作れます。
titleLabel.setBorder(BorderFactory.createEmptyBorder(50, 10, 20, 10));この指定は、上、左、下、右の余白を設定しています。
| 順番 | 意味 |
|---|---|
| 50 | 上の余白 |
| 10 | 左の余白 |
| 20 | 下の余白 |
| 10 | 右の余白 |
余白がない画面は、部品が詰まって見えます。
逆に、適切な余白を入れると、タイトルやボタンが見やすくなり、操作しやすい画面になります。
BorderLayout:上下左右中央に配置する
BorderLayout は、画面を5つの領域に分けて部品を配置するレイアウトです。
| 領域 | 位置 |
|---|---|
| BorderLayout.NORTH | 上 |
| BorderLayout.SOUTH | 下 |
| BorderLayout.WEST | 左 |
| BorderLayout.EAST | 右 |
| BorderLayout.CENTER | 中央 |
タイトル画面では、上にタイトル、中央に説明文やジャンル選択、ボタンを置くような構成にできます。
JPanel panel = new JPanel(new BorderLayout());
panel.add(titleLabel, BorderLayout.NORTH);
panel.add(centerPanel, BorderLayout.CENTER);このように書くと、titleLabel が上部、centerPanel が中央に配置されます。
BorderLayout は、大きな画面構成を作るときに便利です。
細かい部品の並びは別の JPanel に任せ、全体の配置を BorderLayout で整えると、画面が整理されます。
BoxLayout:縦方向に部品を並べる
BoxLayout は、部品を縦や横に並べるためのレイアウトです。
タイトル画面では、説明文、ジャンル選択、スタートボタンを縦に並べるために使えます。
centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));BoxLayout.Y_AXIS は、縦方向に並べる指定です。
| 指定 | 内容 |
|---|---|
| BoxLayout.Y_AXIS | 縦方向に並べる |
| BoxLayout.X_AXIS | 横方向に並べる |
さらに、Box.createVerticalStrut を使うと、部品の間に縦方向の空白を入れられます。
centerPanel.add(Box.createVerticalStrut(25));これにより、説明文とジャンル選択、ジャンル選択とスタートボタンの間に余白を作れます。
タイトル画面の部品構成
ここまで見てきた部品を組み合わせると、タイトル画面は次のような構造になります。
| 部品 | 役割 |
|---|---|
| JFrame | アプリ全体のウィンドウ |
| mainPanel | 画面切り替え用の親パネル |
| titlePanel | タイトル画面用のパネル |
| JLabel | アプリタイトルや説明文を表示 |
| JComboBox | ジャンルを選ぶ |
| JButton | スタートする |
| BorderLayout | タイトルと中央エリアを配置 |
| BoxLayout | 中央エリアの部品を縦に並べる |
この構造を理解しておくと、後で完成版の QuizGame.java を読んだときに、画面がどのように作られているか分かりやすくなります。
CUI版とGUI版の違い
ここで、CUI版とGUI版の違いを整理しておきます。
| 項目 | CUI版 | GUI版 |
|---|---|---|
| 表示方法 | 文字を順番に表示する | ウィンドウに部品を配置する |
| 操作方法 | キーボードで番号入力 | ボタンや選択リストを操作 |
| ジャンル選択 | 数字を入力 | JComboBox から選ぶ |
| 回答方法 | 1~4 を入力 | 選択肢ボタンをクリック |
| 画面遷移 | 文字の流れで進む | CardLayout で画面を切り替える |
| エラー表示 | 文字で表示 | JOptionPane などで表示できる |
CUI版では、処理の順番がそのまま画面に出ます。
GUI版では、画面部品とイベント処理を組み合わせて、ユーザーの操作に反応する形になります。
この違いを理解することが、Swing学習の大きな入口です。
図:Swingで作るクイズゲーム画面の土台
↓クリックすると拡大表示されます。

この図が示していること
Swingアプリでは、JFrame を土台にして、その中に JPanel を置き、CardLayout によってタイトル画面、クイズ画面、結果画面を切り替える構造になっていることを示しています。
この図から分かること
GUIアプリは、1つのウィンドウの中に複数の画面を用意し、必要に応じて表示する画面を切り替えることで進行することが分かります。
図:タイトル画面で使うSwing部品
↓クリックすると拡大表示されます。

この図が示していること
タイトル画面が、JLabel、JComboBox、JButton などのSwing部品を組み合わせて作られていることを示しています。
この図から分かること
GUI画面は、ひとつの大きな命令で作るのではなく、小さな部品を組み合わせて構成することが分かります。また、Font や Color などを使って見た目を整えることも理解できます。
次の記事につながるポイント
今回の記事では、Swingとは何か、AWTではなくSwingを使う理由、そしてクイズゲームのGUI化で使うSwing部品の前半を見てきました。
ここで特に大切なのは、次の考え方です。
| ポイント | 内容 |
|---|---|
| JFrame | アプリのウィンドウを作る |
| JPanel | 部品を置く領域を作る |
| CardLayout | タイトル、クイズ、結果画面を切り替える |
| JLabel | 文字を表示する |
| JButton | クリック操作を受け取る |
| JComboBox | ジャンル選択を行う |
| レイアウト | 部品を見やすく配置する |
次の記事「改良3:クイズゲームのためのSwing入門②」では、クイズゲームで使用したSwingの命令の後半部分を扱います。
具体的には、イベント処理、ActionListener、ActionEvent、Timer、JOptionPane、SwingUtilities.invokeLater など、ユーザー操作に反応して画面を動かすための仕組みを中心に解説していきます。
