Index > 矢印を簡単に描画するシェイプの自作(Java2D)
Fri, February 15, 2008

矢印を簡単に描画するシェイプの自作(Java2D)

矢印の描画自体は、矢印を構成する各頂点を 線で結んでいくだけなので、単純です。 (頂点の計算はちょっと面倒かもしれませんが)

とはいえ、何本の矢印を描画する必要がある場合、 都度描画するのは面倒なので、 始点(p0)と終点(p1)だけ指定したら、 矢印を描画するShapeクラスをつくりました。

使い方

矢印を描画するコードをArrowShapeクラスに集約して いるので、以下のように、始点(p0)と終点(p1)を指定して、描画します。

ArrowShape a=new ArrowShape(p0,p1);
g2.fill(a);

code

ArrowShape

実体は、 GeneralPathそのものですが、 GeneralPathはfinalクラスであり、サブクラスをつくれない(extendsできない)ため、 AbstractShape.java というShapeインタフェースを実装したスーパークラスを用意しています。

AbstractShape.java

このクラスを使えば実質的にGeneralPathのサブクラスをつくれるのと同じになります。
AbstractShapeを基底クラスとしてArrowShapeをつくり、 getMyShape() メソッドを実装します。 このメソッド内で、GeneralPathを使ってカスタマイズして返します。

ArrowShape.java

import java.awt.*;
import java.awt.geom.*;

public class ArrowShape extends AbstractShape{

    private Point p0;
    private Point p1;
    public ArrowShape(Point p0,Point p1){
        this.p0=p0;
        this.p1=p1;
    }

    private GeneralPath shape;
    protected Shape getMyShape(){
        if(shape==null){
            shape=new GeneralPath();

            ArrowPointCalcUtil util=new ArrowPointCalcUtil( this.p0,this.p1 );

            Point2D p2=util.getPoint2();
            Point2D p3=util.getPoint3();

            Line2D line0=new Line2D.Float(this.p0,this.p1);
            Line2D line1=new Line2D.Float(this.p1,p2);
            Line2D line2=new Line2D.Float(this.p1,p3);

            shape.append(line0,false);
            shape.append(line1,false);
            shape.append(line2,false);
        }
        return shape;
    }
}

※矢印の各頂点の計算は、 ArrowPointCalcUtil.java で行っています。

スーパークラスのコードはこちら

TestFrame

ArrowShapeのテスト用のコード。

TestFrame.java

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class TestFrame extends JFrame{

    public TestFrame(){
        super();
        getContentPane().add(new ArrowCanvas(),BorderLayout.CENTER);
    }

    public static void main(String[] args){
        TestFrame f=new TestFrame();
        f.setSize(160,160);
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setVisible(true);
    }
}

class ArrowCanvas extends JComponent{

    private ArrowShape as0,as1,as2;
    public ArrowCanvas(){
        super();

        {
            Point a=new Point(10,10);
            Point b=new Point(100,100);
            as0=new ArrowShape(a,b);
        }       
        {
            Point a=new Point(10+30,10);
            Point b=new Point(100+30,100);
            as1=new ArrowShape(a,b);
        }       
        {
            Point a=new Point(100,10);
            Point b=new Point(10,100);
            as2=new ArrowShape(a,b);
        }       

    }

    protected void paintComponent(Graphics g) {
        Graphics2D g2=(Graphics2D)g;
        g2.draw(as0);
        g2.draw(as1);
        g2.draw(as2);
    }
}
 Twitter
follow me on Twitter
 Categories