目次 | 前の項目 | 次の項目 | 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
オブジェクトを作成するための便利なメソッド群が提供されています。
getTranslateInstance
getRotateInstance
getScaleInstance
getShearInstance
これらのメソッドを使って作成する変換の特性を指定すると、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.