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

Java入門

Java図形描画の基本!直線や円を5分で描くGraphics入門

トム

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

Javaでの図形描画は、基本さえ押さえれば決して難しくありません。標準ライブラリであるSwingとAWTを組み合わせるだけで、誰でも簡単に直線や円、複雑なアニメーションまで作成できます。

私はかつて、業務系システムの開発現場で10年以上Javaエンジニアとして働いていました。新人の頃、画面にグラフを表示する要件があり、図形描画の仕組みが理解できずに深夜まで悩み続けた経験があります。当時の私と同じように「GUIプログラミングは敷居が高い」と感じている方は多いでしょう。

この記事を読めば、Javaを使った図形描画の基礎から、アニメーションの実装、簡易的なお絵かきツールの作成まで、体系的な知識が身につきます。

Javaの図形描画とは?できることと基本仕様

Javaで図形を描画するには、OSに依存しないウィンドウツールキットであるAWT(Abstract Window Toolkit)や、それを拡張したSwingを利用します。これらはJava標準ライブラリに含まれており、特別なインストール作業なしですぐに使用可能です。

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

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

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

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

Javaの描画処理が動く仕組み(Graphicsクラスの基礎)

図形を描画する際、中心的な役割を果たすのがGraphicsクラスです。このクラスは、画用紙にお絵かきをするための「筆セット」のようなものだと考えてください。

プログラマは「筆(Graphicsオブジェクト)」を受け取り、その筆に対して「線を引け」「色を変えろ」と命令を出します。実際の画面への反映は、Javaのシステム側が自動的に管理してくれるため、私たちは「何を描くか」という命令だけに集中すればよいのです。

図形描画でよく使われる主要API(Graphics/Graphics2D)

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

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

現代のJava開発では、より高品質な描画が求められるため、機能が豊富なGraphics2Dを使用するケースがほとんどです。この記事でも、実用性を重視してGraphics2Dの使い方を重点的に解説します。

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

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

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

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

  • JDK(Java Development Kit): バージョン8以降であれば問題ありません。
  • IDE(統合開発環境): EclipseやIntelliJ IDEA、VSCodeなど、普段使い慣れているもので構いません。

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

Javaで図形を描画するには、まずウィンドウ(JFrame)を作成し、その中に描画エリア(JPanel)を配置するのが定石です。JFrameに直接描画もできますが、画面のチラつきが発生しやすいため推奨されません。

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

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

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

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

このメソッドは、画面を再描画する必要があるタイミングで、システムから自動的に呼び出されます。例えば、ウィンドウが開いた瞬間や、ウィンドウサイズが変更されたときなどです。私たちはこのメソッドの中に「描きたい内容」を記述しておくだけで、あとはJavaが適切なタイミングで実行してくれます。

Javaで基本図形を描画する方法【サンプルコード付き】

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

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

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軸の方向が逆になる点に注意してください。

四角形や円を描く 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);

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

Graphics2Dを使った高度な描画(アンチエイリアスや色指定)

単純な図形だけでなく、滑らかで美しいグラフィックを描画するにはGraphics2Dクラスへのキャストが必要です。これにより、表現力が格段に向上します。

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

paintComponentメソッドの引数はGraphics型ですが、実体はGraphics2Dオブジェクトです。そのため、以下のようにキャストして機能を開放します。

Graphics2D g2 = (Graphics2D) g;

これで、線の太さ変更や透過処理などが可能になります。

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

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

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

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

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);

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

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);
        }
    }
}

このコードを動かせば、マウスをドラッグした場所に黒い点が連続して描画され、線のように見えます。

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

色や太さを変えるには、座標だけでなく「その時点での色」や「太さ」の情報も一緒に保存する必要があります。カスタムクラスを作成し、座標・色・太さをセットでリスト管理するように改良すれば、ペイントソフトのような機能も実現可能です。

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

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

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

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

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

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

変数の値を変更しても画面が変わらない場合は、必ずrepaint()を呼んでいるか確認してください。値を変えただけでは、paintComponentは自動的に再実行されません。開発者が「画面を更新して!」とシステムに依頼する必要があります。

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

アニメーション時に画面が一瞬白くなったり、チラついたりすることがあります。SwingのJPanelはデフォルトで「ダブルバッファリング」という機能が有効になっており、通常はチラつきません。

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

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

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

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

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

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

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

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

ここからさらにスキルアップしたい場合、キーボード入力と組み合わせたアクションゲームや、ボタンやテキストボックスを配置した実用ツールの開発に挑戦してみてください。描画ロジックとユーザー操作を組み合わせることで、プログラミングの楽しさが何倍にも広がります。

JavaFXやProcessingとの比較

今回は標準のSwingを使用しましたが、より現代的でリッチなUIを作りたい場合はJavaFXを学ぶのも良い選択肢です。また、アート作品やビジュアルプログラミングに特化したいなら、JavaベースのProcessingという環境もおすすめです。

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

トム

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

-Java入門