本ページはプロモーションが含まれています

Java入門

【Java】図形描画の基本|Graphicsで直線・円・アニメーションまで解説

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

Javaで直線や円などの図形を描画するには、標準ライブラリのGraphicsクラスを使います。

特別なインストールは不要で、JDKだけあればすぐに始められます。

drawLineやfillOvalといった基本メソッドで図形を描き、Graphics2Dでアンチエイリアスをかけ、Timerでアニメーションさせる。

この3ステップさえ押さえれば、マウスで描けるお絵かきツールまで自分の手で実装できるようになります。

私は業務系Javaシステムの開発に10年以上携わってきました。

新人時代に図形描画で苦労した経験をもとに、つまずきやすいポイントも丁寧にカバーしています。

この記事でわかること

  • drawLine・fillOvalなどの基本メソッド
  • Graphics2Dによる高品質な描画
  • Timerを使ったアニメーション
  • マウスで描けるお絵かきツールの実装

Java Graphicsとは?できることと基本仕様

Java標準ライブラリで描画できる図形の種類を示す図解

Javaで図形を描画するには、OSに依存しないウィンドウツールキットが必要です。

AWT(Abstract Window Toolkit)や、それを拡張したSwingを利用します。

これらはJava標準ライブラリに含まれており、特別なインストール作業なしですぐに使用可能です。

Graphicsクラスとは、Java標準ライブラリに含まれる、ウィンドウに直線・円・文字・画像などを描画するための機能を提供するクラスです。

JDKに標準で含まれているため、追加のライブラリを導入せずに使えます。

Java標準ライブラリで描画できる図形の種類

Javaの標準機能だけで、驚くほど多様な表現が可能です。主に以下のような図形や要素を描画できます。

  • 基本線: 直線、点線
  • 幾何学図形: 長方形、円(楕円)、円弧、多角形
  • 文字: フォント指定可能なテキスト
  • 画像: JPEGやPNGなどのイメージファイル

これらの要素を組み合わせれば、ビジネス用のグラフ作成から、アクションゲームのキャラクター描画まで幅広く応用できます。

描画処理が動く仕組み

図形を描画する際、中心的な役割を果たすのがGraphicsクラスです。

このクラスは、画用紙にお絵かきをするための「筆セット」のようなものだと考えてください。

プログラマは「筆(Graphicsオブジェクト)」を受け取り、その筆に対して「線を引け」「色を変えろ」と命令を出します。

実際の画面への反映は、Javaのシステム側が自動的に管理してくれるため、私たちは「何を描くか」という命令だけに集中すればよいのです。

主要API|GraphicsとGraphics2D

描画に使用するクラスは大きく分けて2つあります。

  1. Graphics: 基本的な描画機能を提供します。線や単純な図形の描画に使用します。
  2. Graphics2D: Graphicsを拡張したクラスです。線の太さを変えたり、図形を回転させたり、滑らかな描画(アンチエイリアス)を行ったりする場合に使用します。

現代のJava開発では、より高品質な描画が求められるため、機能が豊富なGraphics2Dを使用するケースがほとんどです。

本記事でも、実用性を重視してGraphics2Dの使い方を重点的に解説します。

Javaで図形を描くための準備(開発環境と基本設定)

JFrameとJPanelを使った描画準備の流れを示す図解

コードを書く前に、図形を表示するためのキャンバスを用意しましょう。Javaでウィンドウを表示し、その中に絵を描くための土台を作ります。

最低限必要な環境(JDK・IDE)

図形描画を行うために特別なライブラリは不要です。以下の環境があればすぐに始められます。

  • JDK(Java Development Kit): バージョン8以降であれば問題ありません(2026年9月時点の最新LTSはJDK 25です。JDK 21も2026年9月までサポートが続くため、既存プロジェクトで使い続けても問題ありません)。
  • IDE(統合開発環境): IntelliJ IDEAやEclipse、VSCode(Extension Pack for Java導入済み)など、普段使い慣れているもので構いません。

Swingを使った描画ウィンドウの作成手順

Javaで図形を描画するには、まずウィンドウ(JFrame)を作成し、その中に描画エリア(JPanel)を配置するのが定石です。

JFrameに直接描画もできますが、画面のチラつきが発生しやすいため推奨されません。

手順は以下のとおりです。

  1. JFrameクラスでウィンドウ枠を作る
  2. JPanelを継承したクラスを作る(ここがキャンバスになる)
  3. 作ったパネルをウィンドウに追加する

描画メソッド paintComponent の動作原理

JPanelに図形を描くには、paintComponent(Graphics g)というメソッドをオーバーライド(上書き)します。

このメソッドは、画面を再描画する必要があるタイミングで、システムから自動的に呼び出されます。

例えば、ウィンドウが開いた瞬間や、ウィンドウサイズが変更されたときなどです。

私たちはこのメソッドの中に「描きたい内容」を記述しておくだけで、あとはJavaが適切なタイミングで実行してくれます。

Java基本図形の描画方法|drawLine・drawRect・drawOvalの使い方

drawLineやdrawRectを使った基本図形の描画方法を示す図解

それでは、実際にコードを書いてみましょう。ここでは基本となる直線、四角形、円、多角形の描き方を紹介します。

まずは、以下のベースとなるコードを見てください。このクラスの中に、各図形の描画処理を記述していきます。

import javax.swing.*;
import java.awt.*;

public class DrawingSample extends JPanel {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // ここに描画処理を書く
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Java図形描画サンプル");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.add(new DrawingSample());
        frame.setVisible(true);
    }
}

直線を描画する drawLine の使い方

直線を引くにはdrawLineメソッドを使います。始点と終点の座標を指定するだけです。

// g.drawLine(始点X, 始点Y, 終点X, 終点Y);
g.drawLine(50, 50, 200, 200);

Javaの座標系は、画面の左上が原点(0, 0)です。X座標は右に行くほど大きくなり、Y座標は下に行くほど大きくなります

数学のグラフとはY軸の方向が逆になる点に注意してください。

私が新人時代にハマったのが、数学の座標系とY軸の方向が逆であることでした。

グラフ描画の要件で「Y軸を上向きにしたい」場合は、描画時にY座標をパネルの高さ - 実際のY値で反転させる必要があります。

四角形や円を描く drawRect/drawOval

輪郭線だけの図形を描く場合は、drawで始まるメソッドを使います。

四角形(長方形)

// g.drawRect(左上X, 左上Y, 幅, 高さ);
g.drawRect(50, 50, 100, 60);

円(楕円)

// g.drawOval(左上X, 左上Y, 幅, 高さ);
g.drawOval(200, 50, 80, 80);

drawOvalは指定した長方形に内接する楕円を描きます。幅と高さを同じ値にすれば、正円になります。

塗りつぶし図形の描画(fillRect/fillOval)

中身が塗りつぶされた図形を描くには、fillで始まるメソッドを使います。

// 色を赤に設定
g.setColor(Color.RED);
// 塗りつぶされた四角形
g.fillRect(50, 150, 100, 60);

// 色を青に設定
g.setColor(Color.BLUE);
// 塗りつぶされた円
g.fillOval(200, 150, 80, 80);

setColorで設定した色は、次に別の色を設定するまで維持されます。

多角形の描画(Polygonを使う方法)

三角形や星型など、複雑な多角形を描くにはPolygonクラスを使うか、座標の配列を渡します。

int[] xPoints = {100, 150, 50};
int[] yPoints = {250, 350, 350};
int nPoints = 3; // 頂点の数

g.setColor(Color.GREEN);
g.fillPolygon(xPoints, yPoints, nPoints);

これで緑色の三角形が描画されます。頂点の順番通りに線が結ばれる仕組みです。

テキストを描画する(drawStringの使い方)

文字列を描画するにはdrawStringメソッドを使います。第1引数に表示したい文字列、第2・第3引数にX座標とY座標を指定します。

// g.drawString(文字列, X座標, Y座標);
g.setColor(Color.BLACK);
g.setFont(new Font("SansSerif", Font.BOLD, 20));
g.drawString("Hello, Java!", 50, 300);

注意点として、Y座標は文字のベースライン(文字の底辺)の位置を指します。

文字の上端ではないため、小さい値を指定すると文字が画面外に出てしまうことがあります。

フォントの変更はsetFontメソッドで行い、Font.BOLDFont.ITALICでスタイルも指定できます。

画像を描画する(drawImageの使い方)

JPEGやPNGなどの画像ファイルを描画するには、まずImageIO.read()で画像を読み込み、drawImageメソッドで描画します。

BufferedImage image = ImageIO.read(new File("sample.png"));
// g.drawImage(画像, X座標, Y座標, ImageObserver);
g.drawImage(image, 50, 50, this);

第4引数のImageObserverには、JPanelを継承したクラスなら通常thisを渡します。幅・高さを指定したい場合は4引数版を使います。

g.drawImage(image, x, y, width, height, this)のように書くと、元画像をリサイズして表示できます。

Graphics2Dで高度な描画をする

Graphics2Dによるアンチエイリアスや色指定の高度な描画を示す図解

単純な図形だけでなく、滑らかで美しいグラフィックを描画するにはGraphics2Dクラスへのキャストが必要です。

Graphics2Dを使うことで、表現力が格段に向上します。

Graphics2Dへのキャストとできること

paintComponentメソッドの引数はGraphics型ですが、実体はGraphics2Dオブジェクトです。

そのため、以下のようにキャストして機能を開放します。

Graphics2D g2 = (Graphics2D) g;

Graphics2Dへのキャストにより、線の太さ変更や透過処理などが可能になります。

アンチエイリアスで図形を滑らかにする方法

デフォルトの描画では、斜めの線や円の縁がギザギザに見えてしまいます。これを「ジャギー」と呼びます。

RenderingHintsを設定することで、このギザギザを滑らかに除去できます。

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                    RenderingHints.VALUE_ANTIALIAS_ON);

setRenderingHintの呼び出しを入れるだけで、描画クオリティが劇的に向上します。特別な理由がない限り、常に有効にしておくべき設定です。

Strokeで線の太さやスタイルを変更する

通常のGraphicsでは線の太さは1ピクセル固定です。Graphics2DならBasicStrokeを使って太さや線の種類を変更できます。

// 太さ5ピクセルの実線
g2.setStroke(new BasicStroke(5.0f));
g2.drawLine(50, 50, 300, 50);

// 点線などの複雑なスタイルも設定可能
float[] dash = {10.0f, 5.0f}; // 10px線、5px空白の繰り返し
g2.setStroke(new BasicStroke(3.0f, BasicStroke.CAP_BUTT, 
             BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f));

ColorでRGBや透過を指定する

Colorクラスは定数(Color.REDなど)だけでなく、RGB値やアルファ値(透明度)を細かく指定できます。

// R=255, G=100, B=0 (オレンジ系)
Color customColor = new Color(255, 100, 0);
g2.setColor(customColor);

// 半透明の色(第4引数がアルファ値 0〜255)
Color alphaBlue = new Color(0, 0, 255, 128); // 50%透明
g2.setColor(alphaBlue);
g2.fillRect(100, 100, 200, 200);

透明度を活用すれば、図形が重なった美しい表現が可能になります。

グラデーションの描画(GradientPaint)

2色間で色が滑らかに変化するグラデーションを描くには、GradientPaintを使います。

setPaintメソッドで適用し、通常の図形描画メソッドで塗りつぶすだけです。

GradientPaint gp = new GradientPaint(
    50, 50, Color.RED,    // 開始点と色
    250, 50, Color.YELLOW // 終了点と色
);
g2.setPaint(gp);
g2.fillRect(50, 50, 200, 100);

開始点から終了点に向かって色が変化する四角形が描画されます。

第7引数にtrueを渡すと、色の変化が折り返して繰り返される「循環グラデーション」も作成できます。

図形を回転させる(rotateとAffineTransform)

図形を回転させたいときは、Graphics2Drotateメソッドを使います。

角度はラジアン単位で指定するため、Math.toRadians()で度数からラジアンに変換します。

// 45度回転させる(原点中心)
g2.rotate(Math.toRadians(45));
g2.fillRect(100, 100, 100, 50);

特定の点を中心に回転させたい場合は、角度に加えて中心座標を渡す3引数版を使います。

g2.rotate(角度, 中心X, 中心Y)と書けば、原点からの回転計算を自分で行わずに済みます。

Javaで図形をアニメーションさせる方法

Timerを使ったJavaの図形アニメーションの仕組みを示す図解

静止画だけでなく、動く図形を作ってみましょう。

Javaでのアニメーションは「少しずつ座標を変えて、高速に再描画する」というパラパラ漫画の原理で実現します。

Timerを使ったアニメーションの基本

無限ループ(while(true))で描画を行うと、CPUに負荷がかかりすぎたり、画面が固まったりします。

代わりにjavax.swing.Timerを使用するのがスマートな方法です。

// 10ミリ秒ごとにactionPerformedを実行するタイマー
Timer timer = new Timer(10, e -> {
    // 座標の更新処理など
    repaint(); // 再描画を要求
});
timer.start();

座標を動かして図形を動かす考え方

クラスのメンバ変数として図形の座標(X, Y)を持ち、タイマーの中でその値を加減算します。

int x = 0;
int speed = 5;

// タイマー内の処理
x += speed;
if (x > 400) x = 0; // 画面端に行ったら戻る

repaint()メソッドを呼ぶと、Javaシステムが「できるだけ早くpaintComponentを実行しよう」と判断します。

更新された座標xを使って図形が描画されます。

FPS(描画速度)調整のポイント

アニメーションの滑らかさはFPS(Frames Per Second)で決まります。Timerの第1引数(遅延時間)で調整します。

  • 60FPS(非常に滑らか): 約16ms
  • 30FPS(普通): 約33ms

遅延時間を短くしすぎると処理が追いつかなくなるため、PCの性能に合わせて15ms〜30ms程度に設定するのが一般的です。

あわせて読む

実践例:Javaで簡易お絵かきツールを作る

マウスドラッグで線を引く簡易お絵かきツールの実装例を示す図解

ここまでの知識を応用して、マウスで線を引ける「お絵かきツール」を作ってみましょう。

マウスイベントで描画するしくみ

マウスの動きに合わせて線を引くには、MouseMotionListenerを使用します。

「マウスがドラッグされた」というイベントを検知し、その時の座標を取得して描画につなげます。

ドラッグで線を引く実装例

マウスの軌跡をすべて保存しておく必要があります。Pointクラスのリストを使いましょう。

import java.awt.event.*;
import java.util.ArrayList;

public class SimplePaint extends JPanel {
    // 描画した点を保存するリスト
    private ArrayList<Point> points = new ArrayList<>();

    public SimplePaint() {
        // マウス操作を検知するリスナーを追加
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                // ドラッグした位置を追加して再描画
                points.add(e.getPoint());
                repaint();
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLACK);
        
        // 保存された点をすべて描画(点で線を表現)
        for (Point p : points) {
            g.fillOval(p.x, p.y, 5, 5);
        }
    }
}

SimplePaintクラスを実行すれば、マウスをドラッグした場所に黒い点が連続して描画され、線のように見えます。

ただしこの実装はArrayList<Point>にすべての点を保存し続けます。

長時間ドラッグし続けると点の数が数万個規模まで膨れ上がり、paintComponentの再描画コストが線形に増えていきます

実務では一定数を超えたら確定済みの線をBufferedImageに焼き込み、リストは直近の点だけ保持する設計が一般的です。

色変更やペン太さ変更の実装

色や太さを変えるには、座標だけでなく「その時点での色」や「太さ」の情報も一緒に保存する必要があります。

カスタムクラスを作成し、座標・色・太さをセットでリスト管理するように改良すれば、ペイントソフトのような機能も実現可能です。

あわせて読む

よくあるエラー・つまずきポイントと解決策

Java図形描画でよくあるエラーとつまずきポイントを示す図解

図形描画の実装中によく遭遇するトラブルとその解決法をまとめました。

描画メソッドが呼ばれない問題の原因

コードは正しいはずなのに何も表示されない場合、以下の原因が考えられます。

  • add忘れ: 作成したJPanelをJFrameに追加 (frame.add(panel)) していない。
  • サイズ指定: JPanelのサイズが0になっている(setPreferredSizeなどで指定が必要な場合がある)。
  • 可視化: frame.setVisible(true)を呼び忘れている、または呼ぶ順序が早すぎる。

私の経験では、frame.setVisible(true)をパネル追加より先に呼んでしまうケースが最も多いです。

コンポーネントの追加はすべて完了してからsetVisible(true)を呼ぶことを習慣にしましょう。

画面が再描画されないときの対処法

変数の値を変更しても画面が変わらない場合は、必ずrepaint()を呼んでいるか確認してください。

値を変えただけでは、paintComponentは自動的に再実行されません。開発者が「画面を更新して!」とシステムに依頼する必要があります。

チラつき防止(ダブルバッファリング)

アニメーション時に画面が一瞬白くなったり、チラついたりすることがあります。

SwingのJPanelはデフォルトで「ダブルバッファリング」という機能が有効になっており、通常はチラつきません。

もしAWTのCanvasなどを使っている場合は、手動でダブルバッファリング(裏画面で描画してから表画面に転送する技術)を実装する必要があります。

Swingを使っている限りは気にする必要はほとんどありません。

ただし、paintComponentの中でsuper.paintComponent(g)を呼び忘れると、前の描画内容が残ってしまい、表示が乱れる原因になります。

この1行は必ず記述しましょう。

Swingの自動ダブルバッファリングでも、先述のお絵かきツールのように点数が多く負荷の高い描画では追いつかないことがあります。

そうした場合はBufferedImageに手動でオフスクリーン描画してからdrawImageで一括転送する方式に切り替えると、再描画コストを大幅に抑えられます。

よくある質問

Q1. Java Graphicsとは何ですか?

A1. Java標準ライブラリに含まれる、ウィンドウに図形やテキストを描画するためのクラスです。JDKに標準で含まれており、追加のライブラリなしですぐに使えます。

Q2. GraphicsとGraphics2Dはどちらを使えばいいですか?

A2. 基本的な直線や図形だけならGraphicsで十分ですが、線の太さ変更・アンチエイリアス・グラデーションなど高品質な描画にはGraphics2Dが必要です。現代のJava開発ではGraphics2Dを使うケースがほとんどです。

Q3. Javaで画像を表示するにはどうすればいいですか?

A3. ImageIO.read()で画像ファイルを読み込み、GraphicsのdrawImageメソッドで描画します。第4引数のImageObserverには、JPanelを継承したクラスなら通常thisを渡します。

Q4. Javaのアニメーションはどう実装しますか?

A4. 無限ループではなくjavax.swing.Timerを使います。一定間隔でrepaint()を呼び出し、座標を少しずつ変えながら再描画することでアニメーションを実現します。

Q5. 描画メソッドを書いたのに画面に何も表示されません。なぜですか?

A5. 多くの場合、JPanelをJFrameに追加し忘れている、JPanelのサイズが0のまま、またはsetVisible(true)を呼ぶ順序が早すぎることが原因です。コンポーネントの追加をすべて終えてからsetVisible(true)を呼びましょう。

まとめ:Javaの図形描画を学ぶための次のステップ

Javaでの図形描画は、paintComponentGraphicsオブジェクトの使い方が鍵です。

描画の基本は以下の3点に集約されます。

  1. JPanelを継承し、paintComponentをオーバーライドする
  2. Graphics2Dにキャストして、色や太さを指定する
  3. アニメーションさせるならTimerで座標を変えてrepaintする

これらの基本さえ理解すれば、静的なグラフ表示から動的なゲーム画面まで、あらゆるGUIアプリケーションを作成できるようになります。

ゲーム開発やGUIアプリへの応用

ここからさらにスキルアップしたい場合、キーボード入力と組み合わせたアクションゲームや、ボタンやテキストボックスを配置した実用ツールの開発に挑戦してみてください。

描画ロジックとユーザー操作を組み合わせることで、プログラミングの楽しさが何倍にも広がります。

あわせて読む

JavaFXやProcessingとの比較

今回は標準のSwingを使用しましたが、より現代的でリッチなUIを作りたい場合はJavaFXを学ぶのも良い選択肢です。

JDK 11以降ではJavaFXは標準ライブラリから分離されており、別途openjfxの導入が必要です。

また、アート作品やビジュアルプログラミングに特化したいなら、JavaベースのProcessingという環境もおすすめです。

Processing 4系が2026年時点の最新版です。

3つの使い分けについて私の考えを述べておくと、社内ツールや学習用の簡易アプリならSwing+Graphicsで十分です。

ユーザー向けの本格的なUIが必要ならJavaFX、ビジュアル表現やアート寄りの用途ならProcessingを選ぶ、という判断軸で普段は選んでいます。

  • この記事を書いた人
  • 最新記事

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

-Java入門