LinearGradientPaintクラスによるグラデーションの指定

広告

主に塗りつぶし用としてグラデーションパターンを指定する方法を確認します。「setPaint」メソッドの引数にLinearGradientPaintクラスのオブジェクトを指定します。以前から使われていたGradientPaintクラスをより高度にした線形グラデーションの設定が行えます。

クラス図は次のようになっています。

  • java.lang.Object
  • java.awt.MultipleGradientPaint
  • java.awt.LinearGradientPaint
  • public final class LinearGradientPaint extends MultipleGradientPaint

コンストラクタは次の5つが用意されています。

コンストラクタ
LinearGradientPaint(float startX, float startY, float endX, float endY, float[] fractions, Color[] colors)
デフォルトの NO_CYCLE 繰り返しメソッドと sRGB カラースペースを使用して、LinearGradientPaint を構築します。
LinearGradientPaint(float startX, float startY, float endX, float endY, float[] fractions, Color[] colors, MultipleGradientPaint.CycleMethod cycleMethod)
デフォルトの sRGB カラースペースを使用して、LinearGradientPaint を構築します。
LinearGradientPaint(Point2D start, Point2D end, float[] fractions, Color[] colors)
デフォルトの NO_CYCLE 繰り返しメソッドと sRGB カラースペースを使用して、LinearGradientPaint を構築します。
inearGradientPaint(Point2D start, Point2D end, float[] fractions, Color[] colors, MultipleGradientPaint.CycleMethod cycleMethod)
デフォルトの sRGB カラースペースを使用して、LinearGradientPaint を構築します。
LinearGradientPaint(Point2D start, Point2D end, float[] fractions, Color[] colors, MultipleGradientPaint.CycleMethod cycleMethod, MultipleGradientPaint.ColorSpaceType colorSpace, AffineTransform gradientTransform)
LinearGradientPaint を構築します。

LinearGradientPaintクラスでは始点と終点の2つの点を指定するのはGradientPaintクラスと同じですが、この2点間の間に任意の個数の色を指定してグラデーションの色分布を指定することが出来ます。

またグラデーション方法として非循環式の他に循環式(反射)と循環式(繰り返し)の3パターンから選択できます。(GradientPaintクラスで使っていた循環式は循環式(反射)と同じです)。

それでは2番目のコンストラクタを見てみます。

デフォルトの sRGB カラースペースを使用して、LinearGradientPaint を構築
します。

パラメータ:
  startX - ユーザー空間でグラデーション軸の始点の X 座標
  startY - ユーザー空間でグラデーション軸の始点の Y 座標
  endX - ユーザー空間でグラデーション軸の終点の X 座標
  endY - ユーザー空間でグラデーション軸の終点の Y 座標
  fractions - 0.0 - 1.0 の範囲の数値。 グラデーションでの色分布を指定する
  colors - 各小数値に対応する色の配列
  cycleMethod - NO_CYCLE、REFLECT、 REPEAT のいずれか 
例外: 
  NullPointerException - fractions 配列が null の場合、 colors 配列が
    null の場合、 または cycleMethod が null の場合 
  IllegalArgumentException - 始点と終点が同じ点である場合、
    fractions.length != colors.length である場合、colors のサイズが 2 
    より小さい場合、 fractions の値が 0.0 より小さいか 1.0 より大きい
    場合、 または fractions が厳密な昇順で指定されない場合

1番目と2番目の引数で始点座標を、3番目と4番目の引数で終点座標を指定します。

5番目の引数では区間内で色を設定したい位置を指定します。始点から終点までの区間に対して、始点を「0.0」終点を「1.0」と考えます。その区間に対して色を設定したい位置をfloat型の配列で指定します。

6番目の引数では5番目の引数で指定した色を設定する位置に対して実際の色をColorクラスのオブジェクトの配列で指定します。指定する色の数は5番目の数と同じである必要があります。

具体的には次のように記述します。

float[] dist = {0.0f, 0.4f, 1.0f};
Color[] colors = {Color.RED, Color.WHITE, Color.BLUE};

この場合は区間内で合計3つの位置に色を指定していることになります。なお色を指定する位置で始点である「0.0f」や「1.0f」を指定しなかった場合は始点や終点に一番近い色が指定されたものとして扱われます。

例えば次のように記述した場合を考えてみます。

float[] dist = {0.2f, 0.4f, 1.0f};
Color[] colors = {Color.RED, Color.WHITE, Color.BLUE};

この場合は次のように記述した場合と同じです。

float[] dist = {0.0f, 0.2f, 0.4f, 1.0f};
Color[] colors = {Color.RED, Color.RED, Color.WHITE, Color.BLUE};

7番目の引数ではグラデーションの表示方法を指定します。指定できる値は次の3つです。

グラデーション方式
MultipleGradientPaint.CycleMethod.NO_CYCLE非循環式
MultipleGradientPaint.CycleMethod.REFLECT循環式(反射)
MultipleGradientPaint.CycleMethod.REPEAT循環式(繰り返し)

非循環式の場合は始点と終点の間の区間だけにグラデーションが適用されます。循環式(反射)の場合は始点と終点の外側の区間についてそれぞれの点に対して反射するようにグラデーションが適用されます。循環式(繰り返し)の場合は始点と終点の外側の区間についても始点と終点の間のグラデーションが繰り返し適用されます。

具体的には次のように記述します。

public void paintComponent(Graphics g){
  Graphics2D g2 = (Graphics2D)g;
  
  float[] dist = {0.0f, 0.4f, 1.0f};
  Color[] colors = {Color.RED, Color.WHITE, Color.BLUE};
  
  LinearGradientPaint gradient = new LinearGradientPaint(
      50.0f, 50.0f, 
      190.0f, 110.0f,
      dist,
      colors,
      MultipleGradientPaint.CycleMethod.NO_CYCLE
  );
  g2.setPaint(gradient);

  g2.fill(new Rectangle2D.Double(20, 20, 200, 130));
}

「setPaint」メソッドを実行した後で実行された「draw」メソッド及び「fill」メソッドで設定が反映されます。

Point2Dクラスによる座標指定

2つの点の座標を指定する方法としてPoint2Dクラスのオブジェクトを使用するコンストラクタも用意されています。4番目のコンストラクタを見てみます。

デフォルトの sRGB カラースペースを使用して、LinearGradientPaint を構築
します。

パラメータ:
  start - ユーザー空間内でグラデーション軸の始点を表す Point2D
  end - ユーザー空間内でグラデーション軸の終点を表す Point2D
  fractions - 0.0 - 1.0 の範囲の数値。 グラデーションでの色分布を指定する
  colors - 各小数値に対応する色の配列
  cycleMethod - NO_CYCLE、REFLECT、 REPEAT のいずれか 
例外: 
  NullPointerException - 点のいずれかが null の場合、fractions 配列が
    null の場合、 colors 配列が null の場合、 または cycleMethod が 
    null の場合 
  IllegalArgumentException - 始点と終点が同じ点である場合、
    fractions.length != colors.length である場合、 colors のサイズが 2
    より小さい場合、 fractions の値が 0.0 より小さいか 1.0 より大きい場
    合、または fractions が厳密な昇順で指定されない場合

違いは始点と終点の座標をPoint2Dクラスのオブジェクトを使って指定している点だけです。

Point2Dクラスは二次元空間における座標を表す2つの値を保持するためのクラスです。Point2Dクラスはabstractクラスであるため実際にはサブクラスであるPoint2D.DoubleクラスやPoint2D.Floatクラスを使います。詳しくは『Point2Dクラス』を参照して下さい。

具体的には次のように記述します。

public void paintComponent(Graphics g){
  Graphics2D g2 = (Graphics2D)g;
  
  float[] dist = {0.0f, 0.4f, 1.0f};
  Color[] colors = {Color.RED, Color.WHITE, Color.BLUE};
  
  LinearGradientPaint gradient = new LinearGradientPaint(
      new Point2D.Double(50.0d, 50.0d), 
      new Point2D.Double(190.0f, 110.0f),
      dist,
      colors,
      MultipleGradientPaint.CycleMethod.NO_CYCLE
  );
  g2.setPaint(gradient);

  g2.fill(new Rectangle2D.Double(20, 20, 200, 130));
}

サンプルプログラム

簡単なサンプルを一度試してみます。

PaintTest5.java

import javax.swing.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.*;
import java.awt.Color;
import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint;

public class PaintTest6 extends JPanel{

  public static void main(String[] args){
    JFrame frame = new JFrame();

    PaintTest6 app = new PaintTest6();
    frame.getContentPane().add(app);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds(10, 10, 300, 200);
    frame.setTitle("タイトル");
    frame.setVisible(true);
  }

  public void paintComponent(Graphics g){
    Graphics2D g2 = (Graphics2D)g;

    float[] dist = {0.0f, 0.4f, 1.0f};
    Color[] colors = {Color.RED, Color.WHITE, Color.BLUE};

    LinearGradientPaint gradient = new LinearGradientPaint(
        50.0f, 50.0f, 
        100.0f, 110.0f,
        dist,
        colors,
        MultipleGradientPaint.CycleMethod.NO_CYCLE
        // MultipleGradientPaint.CycleMethod.REFLECT
        // MultipleGradientPaint.CycleMethod.REPEAT
    );
    g2.setPaint(gradient);

    g2.fill(new Rectangle2D.Double(20, 20, 200, 130));
  }
}

上記をコンパイルした後で実行すると次のように表示されます。

LinearGradientPaintによる線形グラデーション

今回はグラデーション方式として非循環式を設定しています。

それではグラデーション方式として「MultipleGradientPaint.CycleMethod.REFLECT」を設定した場合と「MultipleGradientPaint.CycleMethod.REPEAT」を設定した場合の結果だけ見ておきます。

MultipleGradientPaint.CycleMethod.REFLECT:

LinearGradientPaintによる線形グラデーション

MultipleGradientPaint.CycleMethod.REPEAT:

LinearGradientPaintによる線形グラデーション

( Written by Tatsuo Ikura )