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を使ってカスタマイズして返します。
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のテスト用のコード。
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);
}
}