はじめに
GUIに独自の表示を行うには、直接描画を行う機能が必要となります。このために用意されているのが、Graphicsクラスです。このクラスの基本的な使い方をマスターして、コンポーネントに自由に描画できるようになりましょう。
対象読者
- Javaに興味がある、けれどプログラミング経験がない、という人。
- Javaに興味がある、けれど何から手をつければいいか分からない、という人。
- Javaに興味はない、でも何でもいいからプログラミングをしたい、という人。
グラフィック描画の仕組み
AWTやSwingといったGUI構築のライブラリには、各種のコンポーネントが用意されています。これらを組み合わせれば、基本的な画面表示を行うことはでしょう。が、それ以上のことを行うには、独自に描画を行うための機能を理解する必要があります。
AWT/Swingのコンポーネントには、それぞれにGraphicsというクラスが組み込まれています。これはjava.awtパッケージにあるクラスで、そのコンポーネントの表示を行う働きを持つものです。一般に「グラフィック・コンテキスト」と呼ばれるのですが、要するに「描画に関する情報を管理しているもの」と考えてください。
このGraphicsには多数の描画用メソッドが用意されており、それらを呼び出すことでコンポーネントへの図形の描画を行うことができます。またjava.awtパッケージにあることからも分かるように、これはAWT/Swing両方で共通して利用されます。
このGraphicsは、コンポーネントに用意されているgetGraphicsというメソッドで得ることができます。では、実際にGraphicsを利用して描画する簡単なサンプルを作成してみましょう。
package codezine.java; import java.awt.*; import javax.swing.*; public class Sample extends JFrame { Graphics g; public Sample(){ this.setSize(300, 200); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); this.g = this.getGraphics(); // 描画のサンプル g.setColor(Color.RED); g.fillOval(50, 50, 100, 100); g.dispose(); } public static void main(String[] args) { new Sample(); } }

これは、getGraphicsでthis(つまり、表示されているウインドウJFrame)のGraphicsを取得し、そのメソッドを呼び出してウインドウに図形を描画する簡単なサンプルです。実行すると、ウインドウに赤い円が表示されます(ただし! このソースコードには問題があります。詳細は後述)。
さっそく描画を行っている部分を見てみましょう。まず、this.getGraphicsでGraphicsインスタンスを取得していますね。それから、次のようにして描画に使う色を設定しています。
g.setColor(Color.RED);
Graphicsでの図形の描画は「色を設定する」「描画をする」といったことの繰り返しになります。Graphicsでは、描画図形の色に関する情報が保持されており、描画のためのメソッドを実行すると、この保持されている色を使って描画を行うようになります。そこで、最初にsetColorというメソッドを呼び出して描画に使う色を設定しておくのです。
描画の色は、java.awtパッケージのColorクラスを使って指定します。これは色に関する情報を管理するクラスです。RGBの輝度を指定して新たなColorを作成することもできますが、主な色については最初からクラスフィールドとして用意されているのでそれを利用するとよいでしょう。ここではColorクラスのREDというクラスフィールドを使っています。名前から分かるように、赤のColorインスタンスです。
続いて、円の描画を行います。これは、GraphicsクラスのfillOvalというメソッドを使います。このfillOvalは、描画図形の位置と大きさを引数で渡すと指定の図形を描画するというものです。Graphicsの描画メソッドは、大体このように位置と大きさを渡して描画させます。
そして、最後にGraphicsのdisposeというメソッドを呼び出しています。これは、このGraphicsインスタンスを破棄するものです。なんでこんなことをするの? と思うでしょうが、これには深いわけがあります。実は、このGraphicsは、その内部でJava仮想マシン外の機能(要するに、OSにあるAPIなど)の力を借りているのです。このため、インスタンスを作ると、OSのメモリを余計に消費してしまいます。そこで、「getGraphicsでGraphicsを取り出したときには、使い終わったらdisposeしておく」というのが、いわばマナーになっています。
