
Java道|マウス操作で描画する
押した場所に、しるしが現れる。
マウス操作で描画する仕組みを学ぶと、JavaのGUIアプリは「表示する画面」から「操作に応じて描き変わる画面」へ進化します。
これまでのGUIアプリケーションでは、ウィンドウを表示したり、ラベルやボタンを配置したり、画像を読み込んで表示したりしてきました。
Frame でウィンドウを作る。
Label で文字を表示する。
Button で操作できる部品を置く。
MouseListener でマウスが部品に入ったり出たりしたときの処理を書く。
Image と Graphics を使って画像を表示する。
ここまで学ぶと、JavaのGUI画面はかなり豊かになります。
しかし、さらに一歩進むと、ユーザーが操作した位置に応じて、画面そのものを描き変えられるようになります。
たとえば、画面のある場所をマウスで押す。
その位置をJavaが読み取る。
読み取った座標を保存する。
画面を描き直す。
保存した座標に丸や図形を描く。
この流れができるようになると、GUIアプリはただ情報を表示するだけではなく、ユーザーの操作に合わせて反応する画面になります。
鬼滅の刃風にたとえると、鬼殺隊本部の修行場にある大きな修行案内盤を、水月が指で押したとします。
すると、その押した場所に青白く光る「気のしるし」が現れる。
別の場所を押すと、今度はその場所にしるしが移る。
修行案内盤が、隊士の操作に合わせて反応している状態です。
今回のテーマは、この「押した場所に描く」仕組みです。
マウスイベントで押した位置を受け取り、その座標を使って paint の中で図形を描きます。
そして、イベント処理と描画処理をつなぐ重要な役割として repaint が登場します。
この記事では、具体的な例示プログラムとして Sample6.java を使い、マウスで押した場所にオレンジ色の気のしるしを描く流れを、鬼滅の刃風の世界観でやわらかく整理していきます。
マウス操作で描画するとは何か
マウス操作で描画するとは、ユーザーが画面を押した位置を調べ、その場所に図形や画像を描くことです。
通常の描画では、あらかじめ決めた座標に文字や図形を描きます。
たとえば、x が 30、y が 30 なら、その位置に図形を描きます。
int x = 30;
int y = 30;しかし、マウス操作で描画する場合は、この x と y の値を、ユーザーがクリックした場所に合わせて変えます。
| 処理 | 内容 |
|---|---|
| マウスを押す | ユーザーが画面上の場所を指定する |
| 座標を取得する | MouseEvent から x座標、y座標を取り出す |
| 変数に保存する | 取得した座標を x と y に入れる |
| repaint を呼ぶ | 画面を描き直すように依頼する |
| paint が動く | 最新の x と y を使って図形を描く |
鬼滅の刃風にたとえると、修行場の床にある案内盤を水月が押すと、その押した場所の座標が記録されます。
そして記録係が「その位置に気のしるしを描き直してください」と案内盤に伝えます。
案内盤は最新の座標を見て、その場所に丸いしるしを描きます。
つまり、マウス操作で描画するポイントは、次の3つです。
| ポイント | 役割 |
|---|---|
| MouseEvent | 押した場所の情報を持つ |
| x と y | 描画する位置を保存する |
| repaint | 保存した位置で画面を描き直すきっかけを作る |
この3つがつながることで、ユーザーの操作が画面の変化として反映されます。
図:マウス操作で描画する全体の流れ
↓クリックすると拡大表示されます。

この図が示していること
この図は、マウスで画面を押してから、その場所に図形が描かれるまでの流れを表しています。
Frame がマウス操作を受け取ります。
マウスが押されると MouseEvent が発生します。
mousePressed の中で getX と getY を使い、押された位置の座標を取り出します。
その座標を x と y に保存し、repaint を呼びます。
その後、paint が呼ばれ、fillOval を使って保存された座標に丸い図形を描きます。
| 図の要素 | 意味 |
|---|---|
| Frame | マウスイベントを受け取る画面全体 |
| mousePressed | マウスが押されたときに呼ばれる処理 |
| getX、getY | 押した位置の座標を取得する |
| x、y | 描画位置を保存する変数 |
| repaint | 再描画を依頼する |
| paint | 実際に画面へ描画する |
| fillOval | 丸い図形を描く |
この図から分かることは、マウス操作と描画処理は直接ひとつながりで動くのではなく、座標の保存と repaint を間に挟んでつながっているということです。
マウスで描画する例
ファイル名:Sample6.java
import java.awt.*;
import java.awt.event.*;
public class Sample6 extends Frame
{
int x = 30;
int y = 30;
public static void main(String[] args)
{
Sample6 sm = new Sample6();
}
public Sample6()
{
super("気のしるしを描く");
addWindowListener(new SampleWindowListener());
addMouseListener(new SampleMouseAdapter());
setSize(420, 320);
setVisible(true);
}
public void paint(Graphics g)
{
// 見出しを描画する
g.setColor(Color.black);
g.drawString("画面を押すと、その場所に気のしるしが現れます", 60, 60);
// 気のしるしを描画する
g.setColor(Color.orange);
g.fillOval(x, y, 20, 20);
}
class SampleWindowListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
class SampleMouseAdapter extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
// 押した位置を保存する
x = e.getX();
y = e.getY();
// 画面を再描画する
repaint();
}
}
}このプログラムでできること
このプログラムを実行すると、「気のしるしを描く」というタイトルのウィンドウが表示されます。
ウィンドウの中には、次の説明文が表示されます。
画面を押すと、その場所に気のしるしが現れますそして、画面をマウスで押すと、その場所にオレンジ色の丸が描かれます。
最初は x が 30、y が 30 なので、左上寄りの位置に丸が描かれます。

その後、別の場所を押すと、その押した位置に丸が移動します。

| できること | 内容 |
|---|---|
| ウィンドウを表示する | Frame を継承して画面を作る |
| マウス操作を受け取る | addMouseListener で MouseAdapter を登録する |
| 押した位置を取得する | MouseEvent の getX、getY を使う |
| 座標を保存する | x と y に代入する |
| 画面を描き直す | repaint を呼ぶ |
| 丸を描く | paint の中で fillOval を使う |
| 色を変える | setColor で黒やオレンジを指定する |
| 閉じる操作に対応する | WindowAdapter と windowClosing を使う |
鬼滅の刃風にたとえると、鬼殺隊本部の修行案内盤に水月が触れると、その場所にオレンジ色の気のしるしが現れるアプリです。
押した場所が記録され、画面が描き直され、その場所に新しいしるしが出ます。
画面全体がマウスイベントの対象になる
今回のプログラムでは、ボタンではなく Frame に対してマウスイベントを登録しています。
addMouseListener(new SampleMouseAdapter());この行は、Sample6 自身、つまり Frame に対して呼び出されています。
そのため、ウィンドウ全体でマウス操作を受け取る形になります。
前に学んだボタンイベントでは、ボタンがイベントの発生元でした。
bt.addActionListener(new SampleActionListener());この場合、イベントの対象は Button です。
一方、今回の addMouseListener は、Frame に対して登録しているため、画面全体がマウスイベントの対象になります。
| イベント登録 | イベントの対象 |
|---|---|
| bt.addActionListener(...) | ボタン |
| bt.addMouseListener(...) | ボタン |
| addMouseListener(...) | フレーム全体 |
鬼滅の刃風にたとえると、前のボタン操作は「修行開始札だけが反応する」仕組みでした。
今回のプログラムでは、「修行場の案内盤全体が反応する」仕組みです。
画面のどこを押したかを取得できるため、押した場所に図形を描けるようになります。
x と y は描画位置を保存する変数
このプログラムでは、クラスの中に x と y という変数を用意しています。
int x = 30;
int y = 30;この2つは、丸を描く位置を保存するための変数です。
| 変数 | 意味 |
|---|---|
| x | 横方向の位置 |
| y | 縦方向の位置 |
最初は、x が 30、y が 30 です。
そのため、アプリを起動した直後は、左上寄りの位置に丸が描かれます。
その後、マウスで画面を押すと、その位置の座標で x と y が上書きされます。
x = e.getX();
y = e.getY();つまり、x と y は「最後に押された場所」を覚えるための変数です。
鬼滅の刃風にたとえると、水月が修行案内盤のどこを押したかを、記録係が巻物に書き留めているようなものです。
次に画面を描き直すとき、paint はその記録を見て、どこに気のしるしを描くかを決めます。
paint で説明文と丸を描く
画面に実際に描画しているのは paint メソッドです。
public void paint(Graphics g)
{
// 見出しを描画する
g.setColor(Color.black);
g.drawString("画面を押すと、その場所に気のしるしが現れます", 60, 60);
// 気のしるしを描画する
g.setColor(Color.orange);
g.fillOval(x, y, 20, 20);
}この中では、2つの描画を行っています。
| 描画内容 | 使うメソッド |
|---|---|
| 説明文を描く | drawString |
| 丸いしるしを描く | fillOval |
まず、色を黒に設定しています。
g.setColor(Color.black);その後、説明文を描いています。
g.drawString("画面を押すと、その場所に気のしるしが現れます", 60, 60);次に、色をオレンジに変えています。
g.setColor(Color.orange);そして、x と y の位置に丸を描いています。
g.fillOval(x, y, 20, 20);このように、Graphics を使うと、同じ paint の中で文字も図形も描けます。
鬼滅の刃風にたとえると、まず修行案内盤に黒い文字で説明を書き、そのあとオレンジ色の気のしるしを描いている状態です。
fillOval で丸い図形を描く
今回の図形描画の中心は fillOval です。
g.fillOval(x, y, 20, 20);fillOval は、塗りつぶされた楕円を描くメソッドです。
引数の意味は次の通りです。
| 引数 | 意味 |
|---|---|
| x | 楕円を描き始める横位置 |
| y | 楕円を描き始める縦位置 |
| 20 | 楕円の幅 |
| 20 | 楕円の高さ |
幅と高さが同じなので、見た目は丸に近くなります。
今回のプログラムでは、この丸を「気のしるし」として表現しています。
| コード | 描かれるもの |
|---|---|
| g.fillOval(x, y, 20, 20) | x、y の位置に小さな丸を描く |
| g.fillOval(x, y, 40, 40) | より大きな丸を描く |
| g.fillOval(x, y, 20, 40) | 縦長の楕円を描く |
鬼滅の刃風にたとえると、fillOval は修行案内盤に丸い気の印を刻むための命令です。
押した場所にこの丸が描かれることで、ユーザーの操作が目に見える形で画面に残ります。
setColor で描画色を変える
図形や文字の色は setColor で指定します。
今回のプログラムでは、説明文を黒、丸をオレンジにしています。
g.setColor(Color.black);
g.drawString("画面を押すと、その場所に気のしるしが現れます", 60, 60);
g.setColor(Color.orange);
g.fillOval(x, y, 20, 20);Graphics では、setColor で色を設定すると、その後に描くものがその色になります。
| 設定 | その後に描くもの |
|---|---|
| g.setColor(Color.black) | 黒で描かれる |
| g.setColor(Color.orange) | オレンジで描かれる |
| g.setColor(Color.blue) | 青で描かれる |
| g.setColor(Color.red) | 赤で描かれる |
つまり、paint の中では描く順番と色の設定が大切です。
今回の流れは次の通りです。
| 順番 | 処理 |
|---|---|
| 1 | 色を黒にする |
| 2 | 説明文を描く |
| 3 | 色をオレンジにする |
| 4 | 丸を描く |
鬼滅の刃風にたとえると、まず黒い墨で説明文を書き、そのあとオレンジ色の光で気のしるしを描いているようなものです。
図:mousePressed で座標を取得し repaint する
↓クリックすると拡大表示されます。

この図が示していること
この図は、mousePressed の中で行われている処理を詳しく表しています。
ユーザーが画面を押すと MouseEvent が発生します。
MouseEvent には、押された場所の座標情報が入っています。
getX で横座標を取り出し、getY で縦座標を取り出します。
その値を x と y に保存したあと、repaint を呼びます。
repaint は画面を描き直してほしいという依頼です。
その結果、paint が呼ばれ、最新の x と y の位置に fillOval で丸が描かれます。
| 図の要素 | 意味 |
|---|---|
| マウスを押す | mousePressed が呼ばれるきっかけ |
| MouseEvent e | 押した場所の情報を持つ |
| e.getX | 横座標を取得する |
| e.getY | 縦座標を取得する |
| x、y に保存 | 次の描画位置を記録する |
| repaint | 再描画を依頼する |
| paint | 最新の位置に図形を描く |
この図から分かることは、mousePressed は図形を直接描く場所ではなく、押した位置を記録し、再描画を依頼する場所だということです。
mousePressed で押した位置を取得する
マウスを押したときの処理は、SampleMouseAdapter クラスの中に書かれています。
class SampleMouseAdapter extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
// 押した位置を保存する
x = e.getX();
y = e.getY();
// 画面を再描画する
repaint();
}
}mousePressed は、マウスボタンが押されたときに呼ばれるメソッドです。
今回の処理では、まず押された位置を取得しています。
x = e.getX();
y = e.getY();MouseEvent の e には、マウス操作に関する情報が入っています。
その中から getX と getY を使って、クリックされた場所の座標を取り出します。
| メソッド | 分かること |
|---|---|
| getX | 押された場所の横座標 |
| getY | 押された場所の縦座標 |
これにより、ユーザーが画面のどこを押したのかをJavaが知ることができます。
鬼滅の刃風にたとえると、水月が修行案内盤のどの場所に触れたのかを、MouseEvent という通知札が正確に伝えてくれる状態です。
MouseAdapter を使う理由
今回のプログラムでは、MouseListener を直接実装するのではなく、MouseAdapter を継承しています。
class SampleMouseAdapter extends MouseAdapterMouseListener を直接実装すると、mouseClicked、mousePressed、mouseReleased、mouseEntered、mouseExited の5つをすべて書く必要があります。
しかし、今回必要なのは mousePressed だけです。
そのため、MouseAdapter を使うと、必要なメソッドだけを書けます。
| 書き方 | 特徴 |
|---|---|
| MouseListener を実装する | 5つのメソッドをすべて書く必要がある |
| MouseAdapter を継承する | 必要なメソッドだけ書ける |
今回のように、マウスを押したときだけ処理したい場合は、MouseAdapter が便利です。
鬼滅の刃風にたとえると、MouseListener はマウスのすべての動きを見張る正式な見張り係です。
MouseAdapter は、その中から必要な「押されたとき」だけを担当できる補助係のようなものです。
repaint の役割
このテーマで特に大切なのが repaint です。
repaint();repaint は、画面をもう一度描き直してほしいときに呼び出すメソッドです。
ここで注意したいのは、repaint 自体が丸を描いているわけではないことです。
実際に丸を描くのは paint です。
repaint は、Javaに対して「画面を描き直してください」と依頼する役割を持っています。
| メソッド | 役割 |
|---|---|
| repaint | 再描画を依頼する |
| paint | 実際に画面に描画する |
今回の流れは次のようになります。
| 順番 | 起こること |
|---|---|
| 1 | マウスを押す |
| 2 | mousePressed が呼ばれる |
| 3 | x と y が新しい座標に変わる |
| 4 | repaint を呼ぶ |
| 5 | paint が呼ばれる |
| 6 | 新しい x と y の位置に丸が描かれる |
ここで重要なのは、x と y を変更しただけでは、画面の見た目がすぐに変わるとは限らないことです。
変数の値が変わっても、画面を描き直すタイミングが必要です。
そのために repaint を呼びます。
鬼滅の刃風にたとえると、記録係が「次のしるしはこの場所です」と巻物に書き換えただけでは、案内盤の表示はまだ変わりません。
支援隊士が案内盤に「最新の記録で描き直してください」と合図を送る必要があります。
その合図が repaint です。
paint と repaint の関係
paint と repaint は名前が似ているので混同しやすいです。
役割を分けると、かなり分かりやすくなります。
| メソッド | 役割 | 鬼滅の刃風のイメージ |
|---|---|---|
| paint | 実際に画面へ描く | 案内盤に文字やしるしを描く |
| repaint | 描き直しを依頼する | 案内盤へ再描画の合図を送る |
repaint を呼ぶと、その結果として paint が呼ばれます。
ただし、paint を直接呼ぶのではなく、repaint を使って再描画を依頼するのが基本です。
repaint()
↓
Javaが再描画の必要を判断する
↓
paint(Graphics g) が呼ばれる
↓
drawString や fillOval で描くGUIでは、画面は必要に応じて何度も描き直されます。
ウィンドウが表示されたとき、別のウィンドウに隠れて再び見えたとき、サイズが変わったとき、repaint が呼ばれたときなどに paint が呼ばれます。
だから、画面に表示したい内容は paint の中に書いておく必要があります。
変数の変更と画面更新は別のこと
初心者がつまずきやすいポイントは、変数を変えただけでは画面が自動的に変わるとは限らないことです。
今回のコードでは、mousePressed の中で x と y を変更しています。
x = e.getX();
y = e.getY();これで、描画位置のデータは変わりました。
しかし、画面に表示されている丸を新しい位置に描き直すには、再描画が必要です。
そのため、次に repaint を呼びます。
repaint();| 処理 | 意味 |
|---|---|
| x と y を変更する | 描画位置のデータを更新する |
| repaint を呼ぶ | 画面を描き直すように依頼する |
| paint が呼ばれる | 更新後のデータを使って描画する |
鬼滅の刃風にたとえると、修行記録巻物の座標を書き換えるだけでは、案内盤のしるしはまだ古い位置のままです。
案内盤を描き直して、はじめて新しい位置にしるしが出ます。
この「データの更新」と「画面の更新」を分けて考えることが、とても大切です。
イベント処理と描画処理がつながる面白さ
今回の内容では、イベント処理と描画処理が組み合わさっています。
イベント処理は、ユーザーの操作を受け取ります。
描画処理は、画面に文字や図形を描きます。
repaint は、その間をつなぎます。
| 役割 | 内容 |
|---|---|
| mousePressed | マウス操作を受け取る |
| getX、getY | 押された場所を調べる |
| x、y | 描画位置を保存する |
| repaint | 描き直しを依頼する |
| paint | 保存された座標を使って描画する |
| fillOval | 丸い図形を描く |
鬼滅の刃風にたとえると、水月が修行案内盤を押すという行動が、気のしるしとしてその場に現れます。
操作と描画がつながるので、画面が生きているように感じられます。
この考え方が分かると、単なるボタン操作よりも一歩進んだGUI表現ができるようになります。
図:イベント処理と描画処理がつながる仕組み
↓クリックすると拡大表示されます。

この図が示していること
この図は、イベント処理と描画処理が repaint によってつながることを表しています。
左側のイベント処理では、mousePressed がマウス操作を受け取り、MouseEvent から座標を取得して x と y に保存します。
そのあと repaint を呼びます。
中央の repaint は、イベント処理と描画処理をつなぐ橋です。
右側の描画処理では、paint が呼ばれ、drawString で説明文を描き、fillOval で最新の x と y の位置に丸を描きます。
| 図の要素 | 意味 |
|---|---|
| mousePressed | マウス操作を受け取るイベント処理 |
| MouseEvent | 押した位置の情報 |
| x、y | 描画位置の保存場所 |
| repaint | 再描画を依頼する橋渡し |
| paint | 実際に画面を描く処理 |
| fillOval | 気のしるしを描く処理 |
この図から分かることは、マウス操作で描画するプログラムでは、イベント処理と描画処理を分けて考え、その間を repaint でつなぐ必要があるということです。
この考え方を広げると何ができるか
今回の Sample6.java では、押した場所に丸を1つ描いています。
しかし、考え方を広げると、いろいろなGUI表現につながります。
| 応用例 | できること |
|---|---|
| クリックした場所に画像を表示する | 修行カードやキャラクター画像を出す |
| ドラッグした軌跡に線を描く | 簡単なお絵描きアプリを作る |
| クリック位置によって色を変える | 画面領域ごとに違う反応を作る |
| 押すたびに複数の印を残す | 記録型の描画アプリにする |
| 図形の大きさを変える | 押した場所や条件に応じて表現を変える |
| マウス位置を使って判定する | 当たり判定や選択処理につなげる |
鬼滅の刃風にたとえると、今回は1つの気のしるしを出すだけでした。
でも、応用すれば、押した場所に修行札を出したり、マウスの動きに合わせて刀筋の軌跡を描いたり、複数の修行ポイントを地図の上に残したりできます。
今回の基本は、描画アプリやゲーム風の画面表現にもつながる大切な入口です。
コード全体の流れを整理する
Sample6.java の流れを、順番に整理してみます。
| 順番 | 処理 | 役割 |
|---|---|---|
| 1 | Sample6 が Frame を継承する | ウィンドウとして動けるようにする |
| 2 | x と y を用意する | 丸を描く位置を保存する |
| 3 | main で new Sample6 を実行する | アプリを起動する |
| 4 | コンストラクタが動く | 初期設定を行う |
| 5 | addMouseListener を登録する | フレームでマウス操作を受け取る |
| 6 | setSize で大きさを決める | ウィンドウサイズを設定する |
| 7 | setVisible で表示する | 画面を表示する |
| 8 | paint が呼ばれる | 説明文と最初の丸を描く |
| 9 | マウスを押す | mousePressed が呼ばれる |
| 10 | getX、getY で座標を取得する | 押した場所を調べる |
| 11 | x と y を更新する | 新しい描画位置を保存する |
| 12 | repaint を呼ぶ | 再描画を依頼する |
| 13 | paint が再び呼ばれる | 新しい位置に丸を描く |
鬼滅の刃風にたとえると、最初に修行案内盤を設置し、初期位置に気のしるしを描きます。
その後、水月が案内盤を押すたびに、記録係が座標を保存し、支援隊士が案内盤へ再描画の合図を送り、新しい位置に気のしるしが描かれます。
はじめて学ぶときに押さえたい見方
マウス操作で描画するプログラムは、最初は少し流れが多く感じるかもしれません。
その場合は、次の4つの場所に分けて見ると分かりやすくなります。
| 見る場所 | 確認すること |
|---|---|
| イベントを受け取る場所 | addMouseListener |
| 位置を取得する場所 | mousePressed の getX、getY |
| 位置を保存する場所 | x、y への代入 |
| 描画する場所 | paint の fillOval |
| 画面更新を依頼する場所 | repaint |
特に大切なのは、mousePressed の中で直接図形を描くのではなく、座標を保存して repaint を呼ぶという流れです。
図形を描く処理は paint にまとめます。
| 処理 | 書く場所 |
|---|---|
| 押した位置を取得する | mousePressed |
| 描画位置を保存する | mousePressed |
| 再描画を依頼する | mousePressed |
| 実際に図形を描く | paint |
この役割分担が見えると、GUI描画の流れがかなり理解しやすくなります。
この内容でつかんでおきたいこと
今回のテーマでいちばん大切なのは、マウスで押した位置を使って、その場所に描画できるということです。
そのためには、マウスイベント、座標取得、再描画、描画処理がつながる必要があります。
| ポイント | 内容 |
|---|---|
| Frame がソースになる | 画面全体でマウスイベントを受け取れる |
| MouseAdapter | 必要なマウスメソッドだけを書ける |
| mousePressed | マウスを押したときに呼ばれる |
| MouseEvent | マウス操作の情報を持つ |
| getX | 押した場所の横座標を取得する |
| getY | 押した場所の縦座標を取得する |
| x、y | 描画する位置を保存する |
| repaint | 画面の再描画を依頼する |
| paint | 実際に画面を描く |
| Graphics | 描画のための道具 |
| setColor | 描画色を指定する |
| drawString | 文字を描く |
| fillOval | 塗りつぶした楕円を描く |
この仕組みが分かると、JavaのGUIは、ただ部品を置くだけの画面ではなく、ユーザーの動きに合わせて画面を描き変えられるものとして見えてきます。
鬼滅の刃風にたとえると、修行案内盤はもう静かな掲示板ではありません。
隊士が押した場所を覚え、そこに気のしるしを描き、次の操作に合わせて表示を変える、生きた修行装置になります。
