| 目次 | 前の項目 | 次の項目 | JavaTM 2D API プログラマーズガイド |
java.awt.Graphics を継承する Graphics2D では、図形、テキスト、およびイメージの表示について制御できる内容が、一段と高度になっています。Java 2D™ のレンダリング処理は、Graphics2D オブジェクトとその状態属性を使って制御します。
Graphics2D の状態属性には線の形状や変換などがあり、グラフィックオブジェクトがレンダリングされるときに適用されます。Graphics2D に関する状態属性の集合を、Graphics2D 「コンテキスト」と呼びます。テキストや図形やイメージをレンダリングするには、Graphics2D コンテキストを設定してから、draw や fill などの Graphics2D レンダリングメソッドの 1 つを呼び出します。
次の表は、Graphics2D コンテキストに関連して使うインタフェースとクラスの一覧です。 状態属性を表すクラスも含まれています。これらのほとんどのクラスは、java.awt パッケージに含まれています。
Java 2D™ API を使ってグラフィックオブジェクトをレンダリングするには、Graphics2D コンテキストを設定してから、Graphics2D レンダリングメソッドの 1 つににグラフィックオブジェクトを渡します。
Graphics2D コンテキストを構成する状態属性を変更することで、次の操作が可能です。
Graphics2D では、グラフィックスコンテキストの属性を追加または変更するためのメソッドがいくつか定義されています。大部分のメソッドは、Paint オブジェクトや Stroke オブジェクトなど、特定の属性を表すオブジェクトを受け取ります。
Graphics2D コンテキストは、このような属性オブジェクトの「参照」を保持します。属性オブジェクトは複製されません。Graphics2D コンテキストに含まれる属性オブジェクトを変更する場合は、適切な set メソッドを呼び出して、コンテキストに通知する必要があります。レンダリング操作の間に属性オブジェクトを変更すると、予測できない動作をしたり、場合によっては動作が不安定になります。
グラフィックオブジェクトのレンダリングでは、幾何形状、イメージ、および属性の情報がまとめられて、ディスプレイ上で変更する必要のあるピクセル値が算出されます。
Shape のレンダリング処理は、4 つのステップに分けることができます。
Shape でストロークの描画が必要な場合は、Graphics2D コンテキストの Stroke 属性を使って、描画されるパスを囲む新しい Shape を生成します。 Graphics2D コンテキストの変換属性に従って、Shape のパスの座標をユーザ空間からデバイス空間に変換します。Graphics2D コンテキストのクリッピング属性を使って、Shape のパスをクリッピングします。Shape に描画される部分がある場合は、Graphics2D コンテキストの Paint 属性と Composite 属性を使って塗りつぶします。
テキストのレンダリングは、Shape のレンダリングとほぼ同じです。 テキストは個別のグリフとしてレンダリングされて、グリフはそれぞれが Shape です。唯一の違いは、レンダリングの前に、テキストに適用される Font を判別し、Font から適切なグリフを取得する必要があることです。
イメージの処理はテキストや図形とは異なり、変換操作とクリッピング操作はイメージのバウンディングボックスに対して行われます。色の情報はイメージ自体から取り出されて、イメージのピクセルがレンダリング面に合成される際は、色情報のアルファチャネルがそのときの Composite 属性とともに使われます。
Java 2D API では、速度と品質のどちらを優先してオブジェクトをレンダリングするか指定できます。優先情報は、Graphics2D コンテキストの RenderingHints 属性を使ってヒントとして指定します。レンダリングモードの変更に対応していないプラットフォームもあるため、指定したレンダリングヒントが必ず使われるとは限りません。
RenderingHints クラスは、次の種類のヒントをサポートしています。
Graphics2D コンテキストの RenderingHints 属性を設定または変更するには、setRenderingHints を呼び出します。ヒントをデフォルトに設定すると、プラットフォームでのレンダリングのデフォルト設定が使われます。
GeneralPath オブジェクトのような Shape のストロークを描画することは、GeneralPath のセグメントに沿って論理的なペンを走らせることに相当します。Graphics2D の Stroke 属性は、ペンによって描画される軌跡の特性を定義するものです。
Graphics2D コンテキストのストローク属性を定義するには、BasicStroke オブジェクトを使います。BasicStroke では、線の幅、線端のスタイル、セグメントの接合スタイル、破線パターンなどの特性が定義されています。Graphics2D コンテキストの Stroke 属性を設定または変更するには、setStroke メソッドを呼び出します。


たとえば、図 2-3 の最初のイメージは角を付けた接続スタイルを使っており、2 番目のイメージは丸めた接続スタイル、丸めた線端スタイル、および破線パターンを使っています。

Stroke 属性を使う Graphics2D レンダリングメソッドは、draw、drawArc、drawLine、drawOval、drawPolygon、drawPolyline、drawRect、および drawRoundRect です。これらのメソッドを呼び出すと、指定した Shape の輪郭がレンダリングされます。Stroke 属性は線の特性を定義し、Paint 属性はペンによって描画される軌跡の色とパターンを定義するものです。
たとえば、draw(myRectangle) を呼び出すと、次の処理が行われます。
Stroke 属性を、矩形の輪郭線に適用する Shape オブジェクトに変換するShape の外形の内側にあるピクセルに、Paint 属性を適用する 図 2-4 は、この処理を具体例で示したものです。

Graphics2D コンテキストの塗りつぶし属性は、Paint オブジェクトで表されます。Graphics2D コンテキストに Paint オブジェクトを追加するには、setPaint メソッドを呼び出します。
Shape またはグリフを描画すると (Graphics2D.draw、Graphics2D.drawString)、オブジェクトの輪郭線を描画する Shape の内側にあるすべてのピクセルに、Paint が適用されます。Shape を塗りつぶすと (Graphics2D.fill)、Shape の外形の内側にあるすべてのピクセルに、Paint が適用されます。
単純な均一の塗りつぶしは、setColor メソッドで設定できます。Color は、Paint インタフェースのもっとも簡単な実装です。
グラデーションやテクスチャのようなさらに複雑なスタイルで Shape を塗りつぶすには、Java 2D の Paint インタフェースの GradientPaint クラスと TexturePaint クラスを使います。単純な一色塗りで複雑な塗りつぶしを行おうとすると時間のかかる作業になりますが、これらのクラスを使うと手間のかかる作業は必要なくなります。図 2-5 に示す 2 種類の塗りつぶしは、GradientPaint と TexturePaint で簡単に定義できます。

fill を呼び出して Shape をレンダリングすると、システムでは次の処理が行われます。
Shape を構成するピクセルを特定するPaint オブジェクトから各ピクセルの色を取得する|
バッチ処理
|
|---|
| ピクセルを効率よく処理するため、Java 2D API はバッチでピクセルを処理します。特定の走査線の連続したピクセル群またはピクセルのブロックをバッチ処理できます。このバッチ処理は、2 つのステップで行われます。
次に、 |
「クリッピングパス」は、Shape または Image の中のレンダリングが必要な部分を示すものです。Graphics2D コンテキストにクリッピングパスが含まれている場合、Shape または Image で実際にレンダリングされるのは、クリッピングパスの内側にある部分だけです。
Graphics2D コンテキストにクリッピングパスを追加するには、setClip メソッドを呼び出します。任意の Shape を使って、クリッピングパスを定義できます。
クリッピングパスを変更するには、setClip を呼び出して新しいパスを指定するか、あるいは clip を呼び出して、古いクリッピングパスと新しい Shape の交差している部分を新しいクリッピングパスにします。
Graphics2D コンテキストに含まれている変換は、レンダリングでユーザ空間からデバイス空間にオブジェクトを変換するときに使われます。回転や拡大縮小など、これ以外の変換を行うには、その変換を Graphics2D コンテキストに追加します。追加した変換は、レンダリングの際に適用される変換のパイプラインの一部になります。
Graphics2D では、Graphics2D コンテキストの変換を変更する方法がいくつか提供されています。もっとも簡単な方法は、rotate、scale、shear、translate などの Graphics2D 変換メソッドを呼び出すことです。レンダリングで適用する変換の特性を指定すると、Graphics2D が自動的に適切な変更を行います。
現在の Graphics2D の変換に、AffineTransform を明示的に「連結」することもできます。AffineTransform は、グラフィックスプリミティブのグループに対し、平行移動、拡大縮小、回転、変形などの線形変換を行います。既存の変換に新しい変換を連結すると、最後に指定した変換が「最初に」適用されます。現在の変換に新しい変換を連結するには、Graphics2D.transform に AffineTransform を渡します。
Graphics2D クラスには setTransform メソッドも含まれますが、既存の変換に別の座標変換を連結するためにこのメソッドを使用しないでください。setTransform メソッドは Graphics2D オブジェクトの現行の変換を上書きします。この機能は、次のような操作を行う場合に必要です。
JComponent をペイントするGraphics2D オブジェクトの供給者が、レンダリングの変換で効果を得る可能性があるその他のすべての状況
setTransform メソッドは、変換したグラフィックス、テキスト、またはイメージのレンダリング後に、Graphics2D オブジェクトを元の変換に戻す場合に使用します。
Graphics2D では、パラメータとして AffineTransform を受け取る形式の drawImage メソッドも提供されています。このメソッドを使うと、変換のパイプラインを変更しなくても、イメージオブジェクトを描画するときに目的の変換を適用できます。イメージは、Graphics2D コンテキストの現在の変換に新しい変換を連結した場合と同じように描画されます。
|
アフィン変換
|
|---|
|
Java 2D API では、 アフィン変換は、グラフィックスプリミティブのグループに対して線形の変換を行います。直線は直線に、平行線は平行線に、常に変換されますが、点の間の距離および平行ではない線の間の角度は変わります。 アフィン変換は、次の形式の 2 次元行列に基づいて行われます。
変換を組み合わせることで、オブジェクトに適用できる一連の変換群、つまり変換の「パイプライン」を効果的に作成できます。この組み合わせのことを「連結」と呼びます。
前連結は、ユーザ空間ではなくデバイス空間に関係する変換を行うために使います。たとえば、絶対ピクセル空間に関係する変換を実行するには、 |
AffineTransform では、AffineTransform オブジェクトを作成するための便利なメソッド群が提供されています。
getTranslateInstancegetRotateInstancegetScaleInstancegetShearInstance
これらのメソッドを使って作成する変換の特性を指定すると、AffineTransform が適切な変換行列を生成します。変換行列の要素を直接指定して、AffineTransform を作成することもできます。
2 つのグラフィックオブジェクトが重なる場合、重なった部分のピクセルをどのような色でレンダリングするかを決める必要があります。たとえば、赤い矩形と青い矩形を重ねる場合、2 つの図形が共有するピクセルは、赤、青、または 2 つの色の任意の組み合わせでレンダリングすることになります。重なる領域のピクセルの色により、どちらの矩形が上になっていて、どの程度透けて見えるかが決まります。重なるオブジェクトで共有されているピクセルをどのような色でレンダリングするか決める処理を、「重ね合わせ処理」と呼びます。
Java 2D の合成処理モデルの基礎になるのは、Composite と CompositeContext という 2 つのインタフェースです。
使う合成のスタイルを指定するには、setComposite メソッドを呼び出して、Graphics2D コンテキストに AlphaComposite オブジェクトを追加します。Composite インタフェースの実装である AlphaComposite では、さまざまな合成スタイルがサポートされています。このクラスのインスタンスは、既存の色と新しい色を混合する方法を記述した合成の規則を具体的に表しています。
AlphaComposite クラスで使われるもっとも一般的な重ね合わせ規則の 1 つは SRC_OVER で、これは、新しい色 (ソース色) を既存の色 (デスティネーション色) の上に混合するように指定するものです。
|
AlphaComposite の合成規則
|
説明
|
例
|
|---|---|---|
|
CLEAR
|
クリア
|
|
|
DEST_IN
|
デスティネーションが内側
|
|
|
DEST_OUT
|
デスティネーションが外側
|
|
|
DEST_OVER
|
デスティネーションが上
|
|
|
SRC
|
ソース
|
|
|
SRC_IN
|
ソースが内側
|
|
|
SRC_OUT
|
ソースが外側
|
|
|
SRC_OVER
|
ソースが上
|
|
色の「アルファ」値は透明度の単位で、色を重ねたときに前にレンダリングされている色がどの程度遮られるかを、パーセントで示します。 不透明な色 (alpha=1.0) は下になっている色をまったく通さず、透明な色 (alpha=0.0) は下の色を完全に通します。
テキストと Shape のレンダリングでは、アルファ値は Graphics2D コンテキストの Paint 属性から導出されます。Shape とテキストが平滑化される場合、Graphics2D コンテキストの Paint 属性から得られるアルファ値は、ラスタ化されたパスからのピクセルカバレージ情報と結合されます。イメージは独自のアルファ情報を保持しています。 詳細については、「透明度とイメージ」を参照してください。
AlphaComposite オブジェクトを作成する際に、アルファ値を追加指定できます。この AlphaComposite オブジェクトを Graphics2D コンテキストに追加すると、追加したアルファ値により、レンダリングされるグラフィックオブジェクトの透明度が大きくなります。 つまり、各グラフィックオブジェクトのアルファ値に、AlphaComposite のアルファ値が掛けられます。
イメージには、イメージ内の各ピクセルに対する透明度の情報を持たせることができます。「アルファチャネル」と呼ばれるこの情報は、イメージと既存の描画結果を混合するために、Graphics2D コンテキストの Composite オブジェクトと組み合わせて使われます。
たとえば、図 2-6 は、異なる透明度情報を持つ 3 種類のイメージです。どの場合も、イメージは青い矩形に重ねて表示されます。この例では、Graphics2D コンテキストは、合成操作として SRC_OVER を使う AlphaComposite オブジェクトを含んでいるものとします。

最初のイメージでは、すべてのピクセルが完全に不透明 (犬の体) または完全に透明 (背景) になっています。このような効果は、Web ページでよく使われます。2 番目のイメージでは、犬の体の全ピクセルを不透明ではない一定のアルファ値でレンダリングすることにより、青い背景が透けて見えます。3 番目のイメージでは、犬の顔の周囲のピクセルは完全に不透明 (アルファ = 1.0) ですが、顔から離れるに従って、ピクセルのアルファ値は徐々に小さくなっています。
レンダリングのための Graphics2D コンテキストを構成するには、Graphics2D の設定 (set) メソッドを使って、RenderingHints、Stroke、Paint、クリッピングパス、Composite、Transform などの属性を指定します。
RenderingHints オブジェクトは、オブジェクトをレンダリングする方法に関する設定をすべてカプセル化しています。Graphics2D コンテキストにレンダリングヒントを設定するには、RenderingHints オブジェクトを生成し、Graphics2D.setRenderingHints にそれを渡します。
レンダリングモードの変更をサポートしていないプラットフォームもあるので、レンダリングヒントを設定しても、特定のレンダリングアルゴリズムの使用が保証されるわけではありません。
次の例では、平滑化を有効にし、レンダリングのプリファレンスを quality に設定しています。
qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setRenderingHints(qualityHints);
BasicStroke では、Shape の境界線に適用される特性が定義されています。 これには、線の幅と破線パターン、線のセグメントの接続方法、および線端に適用される形状が含まれます。Graphics2D コンテキストにストローク属性を設定するには、BasicStroke オブジェクトを生成し、それを setStroke メソッドに渡します。
ストロークの幅を設定するには、目的の幅を指定して BasicStroke オブジェクトを生成し、setStroke メソッドを呼び出します。
次の例では、ストロークの幅は 12 ポイントに設定し、接続と線端の形状にはデフォルトの設定を使っています。
接続スタイルと線端スタイルを設定するには、目的の属性を指定して BasicStroke オブジェクトを生成します。
次の例では、ストロークの幅は 12 ポイントに設定し、接続部と線端の形状には、デフォルトの設定ではなく、丸みを付けたスタイルを指定しています。
roundStroke = new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); g2.setStroke(roundStroke);
BasicStroke オブジェクトでは、複雑な破線パターンを簡単に定義できます。そのためには、BasicStroke オブジェクトを作るときに、破線パターンを制御する 2 つのパラメータを指定します。
dash—破線パターンを表す配列。配列の要素は、交互に、ダッシュ部分のサイズとダッシュ間の空白部分のサイズを表す。要素 0 は最初のダッシュ部分を示し、要素 1 は最初の空白部分を示すdash_phase—破線パターンの始まる位置を定義するオフセット次の例では、2 種類の破線パターンが線に適用されています。第 1 のパターンでは、ダッシュのサイズとダッシュ間の空白部のサイズは一定です。第 2 の破線パターンはさらに複雑で、6 つの要素を持つ配列を使って、破線パターンが定義されています。
float dash1[] = {10.0f};
BasicStroke bs = new BasicStroke(5.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
g2.setStroke(bs);
Line2D line = new Line2D.Float(20.0f, 10.0f, 100.0f, 10.0f);
g2.draw(line);
float[] dash2 = {6.0f, 4.0f, 2.0f, 4.0f, 2.0f, 4.0f};
bs = new BasicStroke(5.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10.0f, dash2, 0.0f);
g2.setStroke(bs);
g2.draw(line);
どちらの破線パターンも破線のオフセットは 0 で、破線の描画は破線パターンの先頭から始まっています。この 2 種類の破線パターンを図 2-7 に示します。
Graphics2D コンテキストの Paint 属性により、テキストと Shapes のレンダリング時に使われる塗りつぶしの色とパターンが決まります。
GradientPaint クラスは、ある色から別の色へのグラデーションで図形を塗りつぶす簡単な方法を提供しています。GradientPaint を作るときに、開始の位置と色および終了の位置と色を指定します。塗りつぶしの色は、2 つの位置を結ぶ線に沿って、1 つの色から別の色まで、一定の比率で段階的に変化します。図 2-8 は、グラデーションを使った塗りつぶしの例です。

図 2-8 の第 3 の星型では、開始位置と終了位置が両方とも図形の内部にあります。グラデーションの向きを示す線を P1 より先に延長した部分にある点は、すべて開始位置の色で描画されて、グラデーション線を P2 より先に延長した部分にある点は、すべて終了位置の色で描画されます。
ある色から別の色へのグラデーションで図形を塗りつぶす場合は、次の手順で行います。
GradientPaint オブジェクトを生成するGraphics2D.setPaint を呼び出すShape を作成するGraphics2D.fill(shape) を呼び出す次の例では、青と緑のグラデーションで矩形を塗りつぶしています。
GradientPaint gp = new GradientPaint(50.0f, 50.0f, Color.blue 50.0f, 250.0f, Color.green); g2.setPaint(gp); g2.fillRect(50, 50, 200, 200);
TexturePaint クラスでは、繰り返しパターンで図形を塗りつぶす簡単な方法が提供されています。TexturePaint を作るときは、パターンとして使う BufferedImage を指定します。コンストラクタには、パターンの繰り返し単位を定義する矩形も渡します。 図 2-9 はこの塗りつぶしの例です。

テクスチャによる図形の塗りつぶしは、次の手順で行います。
TexturePaint オブジェクトを生成するGraphics2D.setPaint を呼び出すShape を作成するGraphics2D.fill(shape) を呼び出す次の例では、バッファリングされたイメージから作られた簡単なテクスチャで、矩形を塗りつぶしています。
// Create a buffered image texture patch of size 5x5 BufferedImage bi = new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB); Graphics2D big = bi.createGraphics(); // Render into the BufferedImage graphics to create the texture big.setColor(Color.green); big.fillRect(0,0,5,5); big.setColor(Color.lightGray); big.fillOval(0,0,5,5); // Create a texture paint from the buffered image Rectangle r = new Rectangle(0,0,5,5); TexturePaint tp = new TexturePaint(bi,r,TexturePaint.NEAREST_NEIGHBOR); // Add the texture paint to the graphics context. g2.setPaint(tp); // Create and render a rectangle filled with the texture. g2.fillRect(0,0,200,200); }
クリッピングパスの定義は、次の手順で行います。
Shape を作成するGraphics2D.setClip を呼び出し、作成した Shape を Graphics2D コンテキストのクリッピングパスとして設定するクリッピングパスの縮小は、次の手順で行います。
Shape を作成するclip を呼び出し、クリッピングパスを、現在のクリッピングパスと新しい Shape の共通部分に変更する
次の例では、まず楕円形でクリッピングパスを作成し、次に clip を呼び出してクリッピングパスを変更しています。
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// The width and height of the canvas
int w = getSize().width;
int h = getSize().height;
// Create an ellipse and use it as the clipping path
Ellipse2D e = new Ellipse2D.Float(w/4.0f,h/4.0f,
w/2.0f,h/2.0f);
g2.setClip(e);
// Fill the canvas. Only the area within the clip is rendered
g2.setColor(Color.cyan);
g2.fillRect(0,0,w,h);
// Change the clipping path, setting it to the intersection of
// the current clip and a new rectangle.
Rectangle r = new Rectangle(w/4+10,h/4+10,w/2-20,h/2-20);
g2.clip(r);
// Fill the canvas. Only the area within the new clip
// is rendered
g2.setColor(Color.magenta);
g2.fillRect(0,0,w,h);
}
Shape、テキスト文字列、または Image を変換するには、レンダリングする前に、Graphics2D コンテキストの変換パイプラインに新しい AffineTransform を追加します。グラフィックオブジェクトをレンダリングすると、変換が適用されます。
たとえば、次は、矩形を 45 度回転させて描画する手順です。
Graphics2D 変換を取得する。変換をグラフィックスコンテキストに追加する前に、Graphics2D に対して getTransform を常に呼び出す (グラフィックスコンテキストが、ウィンドウ内で Swing コンポーネントや軽量コンポーネントの位置指定など、他の理由で必要な変換を保持する場合があるため) AffineTransform.getRotateInstance を呼び出し、回転変換を取得する Graphics2D.transform を呼び出し、変換パイプラインに新しい変換を追加するsetTransform を実行すると、グラフィックスコンテキスト内の現在の変換が上書きされてしまうため、新しい座標変換を追加するのに setTransform は使用しないRectangle2D.Float オブジェクトを生成する Graphics2D.draw を呼び出し、矩形をレンダリングする setTransform を呼び出すことにより、Graphics2D の変換をステップ 1 で保存した元の変換に戻す
次の例では、矩形をレンダリングするときに、AffineTransform のインスタンスを使って矩形を 45 度回転させています。
AffineTransform aT = g2.getTransform();Rectangle2D rect = new Rectangle2D.Float(1.0,1.0,2.0,3.0); AffineTransform rotate45 = AffineTransform.getRotateInstance(Math.PI/4.0,0.0,0.0) g2.transform(rotate45); g2.draw(rect);g2.setTransform(aT);
次の例では、AffineTransform を使って、中心点を軸にテキスト文字列を回転させています。
// Define the rendering transform AffineTransform at = new AffineTransform(); // Apply a translation transform to make room for the // rotated text. at.setToTranslation(400.0, 400.0); g2.transform(at); // Create a rotation transform to rotate the text at.setToRotation(Math.PI / 2.0); // Render four copies of the string “Java” at 90 degree angles for (int i = 0; i < 4; i++) { g2.drawString(“Java”, 0.0f, 0.0f); g2.transform(at); }
イメージも同じ方法で変換できます。 レンダリングされるグラフィックオブジェクトの種類に関係なく、レンダリングの際には Graphics2D コンテキストの変換が適用されます。
Graphics2D コンテキストで定義されている変換を変更しないで、イメージに変換を適用するには、drawImage メソッドに AffineTransform を渡します。
AffineTransform rotate45 = AffineTransform.getRotateInstance(Math.PI/4.0,0.0,0.0) g2.drawImage(myImage, rotate45);
Font に変換を適用して、見た目の異なる Font を作ることもできます。 詳細については、「フォント派生の作成」を参照してください。
AlphaComposite は、あるオブジェクトが別のオブジェクトと重なるときの色のレンダリング方法を決める、合成規則をカプセル化しています。Graphics2D コンテキストに合成スタイルを指定するには、AlphaComposite を作成し、それを setComposite メソッドに渡します。もっとも一般的に使われる合成スタイルは SRC_OVER です。
SRC_OVER の合成規則は、デスティネーションピクセルの上にソースピクセルを合成するもので、共有されるピクセルはソースピクセルの色になります。たとえば、青い矩形をレンダリングしてから、それと一部が重なる赤い矩形をレンダリングした場合、重なり合う部分の色は赤になります。つまり、最後にレンダリングされたオブジェクトが、いちばん上に表示されます。
次は、合成規則 SRC_OVER の使用方法です。
SRC_OVER を指定して getInstance メソッドを呼び出し、AlphaComposite オブジェクトを生成するsetComposite メソッドを呼び出し、Graphics2D コンテキストに AlphaComposite オブジェクトを追加する合成オブジェクトがいったん設定されると、重なりを持つオブジェクトは指定されている重ね合わせ規則に従ってレンダリングされます。
AlphaComposite を使うと、アルファ値の定数を追加して指定できます。 この値は、ソースピクセルのアルファ値に掛けられて、ソースピクセルの透明度が高くなります。
たとえば、50% の透過率でソースオブジェクトをレンダリングする AlphaComposite オブジェクトを作るには、アルファに .5 を指定します。
次の例では、ソースを上に重ねるアルファ合成オブジェクトをアルファ値 .5 で作成し、グラフィックスコンテキストに追加しています。その結果、それ以降の図形は 50% の透明度でレンダリングされます。
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red);
g2.translate(100,50);
// radians=degree * pie / 180
g2.rotate((45*java.lang.Math.PI)/180);
g2.fillRect(0,0,100,100);
g2.setTransform(new AffineTransform()); // set to identity
// Create a new alpha composite
AlphaComposite ac =
AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.5f);
g2.setComposite(ac);
g2.setColor(Color.green);
g2.fillRect(50,0,100,100);
g2.setColor(Color.blue);
g2.fillRect(125,75,100,100);
g2.setColor(Color.yellow);
g2.fillRect(50,125,100,100);
g2.setColor(Color.pink);
g2.fillRect(-25,75,100,100);
}
Graphics2D では、Shape、テキスト文字列、および Image のレンダリング用に、次のメソッドが提供されています。
draw—Graphics2D コンテキストの Stroke オブジェクトと Paint オブジェクトを使って、Shape のパスを描画するfill—Graphics2D コンテキストの Paint オブジェクトを使って、Shape を塗りつぶすdrawString—Graphics2D コンテキストの Paint オブジェクトを使って、指定されたテキスト文字列をレンダリングするdrawImage—指定されたイメージをレンダリングする
図形のストロークを描画して塗りつぶすには、draw メソッドと fill メソッドの両方を呼び出す必要があります。
Graphics2D は、drawOval や、fillRect など、旧バージョンの JDK で提供されていた描画用と塗りつぶし用のメソッドもサポートしています。
Shape の輪郭線は、Graphics2D.draw メソッドでレンダリングできます。旧バージョンの JDK で提供されていた次の描画メソッドもサポートされています。drawLine、drawRect、drawRoundRect、drawOval、drawArc、drawPolyline、drawPolygon、draw3DRect。
Shape を描画すると、Graphics2D コンテキストの Stroke オブジェクトでパスが描画されます。詳細については、「ストローク属性」を参照してください。Graphics2D コンテキストに適切な BasicStroke オブジェクトを設定することで、どのような幅とパターンの線でも描画できます。BasicStroke オブジェクトでは、線の先端部と接合部の属性も定義されています。
図形の輪郭線は、次の手順でレンダリングします。
BasicStroke オブジェクトを生成するGraphics2D.setStroke を呼び出すShape を作成するGraphics2D.draw(shape) を呼び出す
次の例では、GeneralPath オブジェクトを使って星型を定義し、BasicStroke オブジェクトを Graphics2D コンテキストに追加して、星型の輪郭線の幅と接合部の属性を定義しています。
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// create and set the stroke
g2.setStroke(new BasicStroke(4.0f));
// Create a star using a general path object
GeneralPath p = new GeneralPath(GeneralPath.NON_ZERO);
p.moveTo(- 100.0f, - 25.0f);
p.lineTo(+ 100.0f, - 25.0f);
p.lineTo(- 50.0f, + 100.0f);
p.lineTo(+ 0.0f, - 100.0f);
p.lineTo(+ 50.0f, + 100.0f);
p.closePath();
// translate origin towards center of canvas
g2.translate(100.0f, 100.0f);
// render the star's path
g2.draw(p);
}
Graphics2D.fill メソッドを使って、任意の Shape を塗りつぶすことができます。Shape を塗りつぶすと、そのパスの内側の領域が、Color、TexturePaint、GradientPaint など、Graphics2D コンテキストの現在の Paint 属性でレンダリングされます。
旧バージョンの JDK で提供されていた次の塗りつぶしメソッドもサポートされています。fillRect、fill3DRect、fillRoundRect、fillOval、fillArc、fillPolygon、clearRect。
Shape を塗りつぶすには、次のようにします。
Graphics2D.setColor または Graphics2D.setPaint を使って、グラフィックスコンテキストの塗りつぶしの色またはパターンを設定するShape を作成するGraphics2D.fill を呼び出し、Shape をレンダリングする
次の例では、setColor を呼び出し、緑色での塗りつぶしを Rectangle2D に定義しています。
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.green);
Rectangle2D r2 = new Rectangle2D.Float(25,25,150,150);
g2.fill(r2);
}
テキスト文字列をレンダリングするには、Graphics2D.drawString を呼び出して、レンダリングする文字列を渡します。テキストのレンダリングとフォントの選択についての詳細は、「フォントとテキストレイアウト」を参照してください。
Image をレンダリングするには、Image を作成し、Graphics2D.drawImage を呼び出します。イメージの処理とレンダリングの詳細については、「イメージング」を参照してください。
Composite インタフェースと CompositeContext インタフェースを実装することで、まったく新しい種類の合成操作を作成できます。Composite オブジェクトでは、実際に状態を保持して合成の作業を行う CompositeContext オブジェクトが提供されます。1 つの Composite オブジェクトから複数の CompositeContext オブジェクトを生成し、マルチスレッド環境の異なる状態を維持できます。
JavaTM 2 SDK のバージョン 1.3 のリリースにより、Java 2DTM API は、ネイティブプラットフォームで構成可能な 3 つの異なるマルチスクリーン構成をサポートします。
Java 2D API を利用することにより、GraphicsConfiguration を使って Frame、JFrame、Window、または JWindow オブジェクトを作成し、レンダリング用の画面デバイスをターゲットにできます。
これら 3 つの設定で、各画面デバイスは GraphicsDevice で表されます。GraphicsDevice は、関連付けられた複数の GraphicsConfiguration オブジェクトを保持できます。
仮想デバイスの構成に複数の画面が使用される場合、物理画面外に存在する仮想座標系が、仮想デバイスの表現に使用されます。マルチスクリーン構成での各 GraphicsConfiguration の座標は、仮想座標系に対する相対座標になります。この環境下で 1 つの画面がメイン画面として認識され、仮想座標系の (0, 0) に配置されます。図 2-10 に示すように、メイン画面の位置によっては、仮想デバイスが負の座標になる場合があります。

Window または Frame が複数の物理画面にまたがる現在の環境が仮想デバイス環境であるかどうかを判別するには、システムの GraphicsConfiguration ごとに getBounds を呼び出して、原点が (0, 0) 以外に位置しているかどうかを調べます。GraphicsConfiguration の getBounds メソッドは、仮想座標系内の Rectangle を返します。このため、原点が (0, 0) 以外の場合には、仮想デバイス環境です。
仮想デバイス環境では、GraphicsConfiguration オブジェクトの座標は仮想座標系に対する相対座標になります。このため、Frame または Window の setLocation メソッドを呼び出す場合には、仮想座標を使用する必要があります。たとえば、以下のコードは、GraphicsConfiguration の境界を取得し、その境界を使って、対応する GraphicsConfiguration の物理画面の原点に対し (10, 10) の位置に Frame を配置します。
Frame f = new Frame(GraphicsConfiguration gc); Rectangle bounds = gc.getBounds(); f.setLocation(10 + bounds.x, 10 + bounds.y);
GraphicsConfiguration の境界が考慮されていない場合、Frame はメインの物理画面の (10, 10) に表示されます。この位置は、指定された GraphicsConfiguration の物理画面とは異なる場合があります。
仮想デバイスの境界判定に、getBounds メソッドを使用することもできます。システムの各 GraphicsConfiguration に対し、getBounds を呼び出します。仮想デバイスの境界を決定するには、すべての境界の和集合を計算します。以下の例に、その具体的な方法を示します。
Rectangle virtualBounds = new Rectangle(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gs = ge.getScreenDevices(); for (int j = 0; j < gs.length; j++) { GraphicsDevice gd = gs[j]; GraphicsConfiguration[] gc = gd.getConfigurations(); for (int i = 0; i < gc.length; i++) { virtualBounds = virtualBounds.union(gc[i].getBounds()); } }
次のアプレットは、GraphicsEnvironment の各 GraphicsDevice の GraphicsConfiguration を使って JFrame を作成します。各 JFrame は、赤、緑、青のストライプセット、画面番号、GraphicsConfiguration の GraphicsConfiguration 番号および境界を表示します。このコード例は、JavaTM 2 SDK バージョン 1.3 以降で動作します。
import java.applet.Applet; import java.awt.*; import javax.swing.*; public class MultiFrameApplet extends Applet { public MultiFrameApplet() { main(null); } public static void main(String[] argv) { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gs = ge.getScreenDevices(); for (int j = 0; j < gs.length; j++) { GraphicsDevice gd = gs[j]; GraphicsConfiguration[] gc = gd.getConfigurations(); for (int i=0; i < gc.length; i++) { JFrame f = new JFrame(gs[j].getDefaultConfiguration()); GCCanvas c = new GCCanvas(gc[i]); Rectangle gcBounds = gc[i].getBounds(); int xoffs = gcBounds.x; int yoffs = gcBounds.y; f.getContentPane().add(c); f.setTitle("Screen# "+Integer.toString(j)+", GC# "+Integer.toString(i)); f.setSize(300, 150); f.setLocation((i*50)+xoffs, (i*60)+yoffs); f.show(); } } } } class GCCanvas extends Canvas { GraphicsConfiguration gc; Rectangle bounds; public GCCanvas(GraphicsConfiguration gc) { super(gc); this.gc = gc; bounds = gc.getBounds(); } public Dimension getPreferredSize() { return new Dimension(300, 150); } public void paint(Graphics g) { g.setColor(Color.red); g.fillRect(0, 0, 100, 150); g.setColor(Color.green); g.fillRect(100, 0, 100, 150); g.setColor(Color.blue); g.fillRect(200, 0, 100, 150); g.setColor(Color.black); g.drawString("ScreenSize="+ Integer.toString(bounds.width)+ "X"+ Integer.toString(bounds.height), 10, 15); g.drawString(gc.toString(), 10, 30); } }
| 目次 | 前の項目 | 次の項目 |
JavaTM 2D API プログラマーズガイド JavaTM 2 SDK, Standard Edition, 1.4 Version |
Copyright © 2003 Sun Microsystems, Inc. All rights reserved.