在之前的课程中,您已经学习了绘图的基本概念,包括坐标系和graphic 对象创建的基本信息。现在,您将了解2D 绘图类的更详细的信息。本科展示如何使用Graphics2D 类绘制基本的几何图形和任意的形状,以及如何使用花哨的轮廓和填充风格展示图形。这些主题分为以下几个章节。
l 绘制基本几何图形:本节展示如何创建标准的集合图形,例如点,线,曲线,圆弧,矩形和椭圆。
l 绘制任意图形:本节展示如何直接使用基本几何图形组合绘制任意形状,使用GeneralPath 类进行绘制。
l 填充和笔画:本节解释如何设置笔画和打印属性,控制应用到Shape 对象和文本的轮廓和填充风格。
Java 2D API 提供很多类,定义了基本的几何对象,例如点,线,弧线和矩形。这些几何类是java.awt.geom 包的一部分。
PathIterator 接口定义了从路径中获取元素的方法。Shape 接口提供了一组描述和解析几何路径的对象。这个接口由GeneralPath 类和其他几何类实现。
本节的所有例子中创建的几何图形都使用java.awt.geom ,然后使用Graphics2D 类进行渲染。要得到Graphics2D 对象,可以cast paint() 方法的Graphics 参数:
public void paint (Graphics g) { Graphics2D g2 = (Graphics2D) g; ... } |
Point 类创建了位于坐标系中(x, y) 位置的点。子类Point2D.Float 和Point2D.Double 提供了使用float 和double 精度存储点。
//Create Point2D.Double Point2D.Double point = new Point2D.Double(x, y); |
要创建位于坐标系(0, 0) 的点,使用默认的构造函数Point2D.Double() 。
您可以使用setLocation 方法设按照下面的方法设置点的位置:
l setLocation(double x, double y) :使用double 坐标值设置点的位置。
l setLocation(Point2D p) :使用坐标系中的其他点设置位置。
同时,Point2D 类中有方法可以计算当前点和给定坐标点之间的距离,或两点之间的距离。
Line2D 表示了(x, y) 坐标系空间中的先片段。Line2D.Float 和Line2D.Double 子类使用float 和double 精度指定了线。例如:
// draw Line2D.Double g2.draw(new Line2D.Double(x1, y1, x2, y2)); |
这个类包含一些setLine() 方法定义线段的端点。同时,线段的断电可以使用构造函数指定,例如:
Line2D.Float(float X1, float Y1, float X2, float Y2) Line2D.Float(Point2D p1, Point2D p2) |
在Graphics2D 类中使用Stroke 对象指定线段路径的笔画。
您可以使用java.awt.geom 包创建二次和三次曲线片段。
QuadCurve2D 类实现了Shape 接口。这个类表示了(x, y) 坐标空间中的二次参数曲线片段。QuadCurve2D.Float 和QuadCurve2D.Double 子类使用float 和double 精度指定了二次曲线。
一些setCurve 方法用来指定曲线的两个端点和控制点,它们的坐标可以直接指定,通过其他点的坐标或使用给定数组。
setCurve(QuadCurve2D c) 是一个非常有用的方法,使用同样的端点和控制点指定曲线,例如:
// create new QuadCurve2D.Float QuadCurve2D q = new QuadCurve2D.Float(); // draw QuadCurve2D.Float with set coordinates q.setCurve(x1, y1, ctrlx, ctrly, x2, y2); g2.draw(q); |
CubicCurve2D 类也实现了Shape 接口。这个类表示了(x, y) 坐标空间中的三次参数曲线片段。CubicCurve2D.Float 和CubicCurve2D.Double 子类使用float 和double 精度指定了三次曲线。
CubicCurve2D 类和QuadraticCurve2D 类有类似的setting 方法。例如:
// create new CubicCurve2D.Double CubicCurve2D c = new CubicCurve2D.Double(); // draw CubicCurve2D.Double with set coordinates c.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2); g2.draw(c); |
下面例子中的类扩展了RectangularShape 类,它实现了Shape 接口,同时自己添加了一些方法。
这些方法让你可以获取图形的位置和大小信息,得到矩形的重点,设置图形的界限。
Rectangle2D 类表示由位置(x, y )和维度(w x h) 定义的矩形。Rectangle2D.Float 和Rectangle2D.Double 子类使用float 和double 精度指定了一个矩形。例如:
// draw Rectangle2D.Double g2.draw(new Rectangle2D.Double(x, y, rectwidth, rectheight)); |
RoundRectangle2D 类定义了位于(x, y) ,维度是(w x h) ,同时定义了圆弧宽度和高度的圆角矩形,RoundRectangle2D.Float 和RoundRectangle2D.Double 子类指定了float 和double 精度的圆角矩形。
圆角矩形指定了以下参数:
l 位置
l 宽度
l 高度
l 角弧的宽度
l 角弧的高度
要设置RoundRectangle2D 对象的位置,大小和弧度,使用方法setRoundRect(double a, double y, double w, double h, double arcWidth, double arcHeight) 。例如:
// draw RoundRectangle2D.Double g2.draw(new RoundRectangle2D.Double(x, y, rectwidth, rectheight, 10, 10));
|
Ellipse2D 类表示由圆角矩形定义的椭圆。Ellipse2D.Float 和Ellipse2D.Double 子类使用float 和double 精度指定了椭圆。
椭圆由位置,宽度和高度完全定义。例如:
// draw Ellipse2D.Double g2.draw(new Ellipse2D.Double(x, y, rectwidth, rectheight));
|
要绘制一片椭圆,您可以使用Arc2D 类。这个类表示了由圆角矩形定义的举行,一个开始角度,一个圆弧扩展和一个关闭类型。Arc2D.Float 和Arc2D.Double 子类表示了float 和double 精度的椭圆。
Arc2D 类定义了下列三种圆弧类型,由以下常量定义:OPEN, PIE 和CHORD 。
一些方法设置了圆弧的大小和参数:
l 使用坐标直接设置
l 使用Point2D 和Dimension2D
l 拷贝已经存在的Arc2D
同时,您可以使用setArcByCenter 方法从中点,通过制定坐标和半径的方式绘制圆弧。
// draw Arc2D.Double g2.draw(new Arc2D.Double(x, y, rectwidth, rectheight, 90, 135, Arc2D.OPEN)); |
ShapesDemo2D.java 源代码中包含所有以上描述的基本几何图形的代码。更详细的信息请参考java.awt.geom 包的API 。
您已经知道如何绘制java.awt.geom 包中的大多数图形。要创建一个更加复杂的集合图形,例如多边形,多边形线段,或者星形。您还可以使用这个包中的另一个类,GeneralPath 。
这个类实现了Shape 接口,同时表示由线段,二次和三次曲线组成的几何路径。这个类中的三个构造函数可以使用默认的弯曲规则(WIND_NON_ZERO ),弯曲规则有(WIND_NON_ZERO 或WIND_EVEN_ODD ),或者特殊的初始化坐标功能。弯曲规则表明如何决定内部路径。
public void Paint (Graphics g) { Graphics2D g2 = (Graphics2D) g; ... } |
要创建一个空的GeneralPath 实例,可以调用new GeneralPath() ,然后使用下列方法向图形中添加片段:
l moveTo(float x, float y) :将路径的当前点移动到给定点。
l lineTo(float x, float y) :向当前路径添加线段片段
l quadTo(float ctrlx, float ctrly, float x2, floaty2) :向当前路径中添加二次方曲线片段
l curveTo(float ctrlx1, float ctrly1, float ctrlx2, float ctrly2, float x3, floaty3) :向当前路径添加三次方曲线片段。
l closePath() :关闭当前路径。
下面的例子展示了如何使用GeneralPath 绘制多边形线条:
// draw GeneralPath (polyline) int x2Points[] = {0, 100, 0, 100}; int y2Points[] = {0, 50, 50, 0}; GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, x2Points.length);
polyline.moveTo (x2Points[0], y2Points[0]);
for (int index = 1; index < x2Points.length; index++) { polyline.lineTo(x2Points[index], y2Points[index]); };
g2.draw(polyline);
|
这个例子展示了如何使用GeneralPath 绘制多边形:
// draw GeneralPath (polygon) int x1Points[] = {0, 100, 0, 100}; int y1Points[] = {0, 50, 50, 0}; GeneralPath polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD, x1Points.length); polygon.moveTo(x1Points[0], y1Points[0]);
for (int index = 1; index < x1Points.length; index++) { polygon.lineTo(x1Points[index], y1Points[index]); };
polygon.closePath(); g2.draw(polygon); |
注意,上面代码的唯一区别在于closePath() 方法。这个方法让绘制多边形线条的最后一个点绘制到开始点。
要将特定的路径加到GeneralPath 对象之后,可以使用append() 方法之一。ShapesDemo2D.java 中有任意形状的实现。
您已经知道如何创建不同的基本集合图形,以及更复杂的图形。本课介绍如何为您的图形添加颜色和特别的轮廓,以及填充和笔画:
l 填充:是使用实心颜色或渐变色或文本填充图形内部的过程。
l 笔画:是绘制图形轮廓时使用的笔画宽度,线形和颜色属性。
要在Graphics2D 上下文渲染前应用特别的线形和填充属性到基本图形中,修改图形的笔画和绘制属性。例如,使用合适的Stroke 对象绘制虚线。要在Graphics2D 上下文线段被渲染之前调用setStroke 方法添加笔画。类似的,要在Shape 对象被渲染之前,将渐变色的填充属性Graphics2D 上下文中。
以下代码使用填充和笔画上下文丰富了几何图形。
// draw RoundRectangle2D.Double
final static float dash1[] = {10.0f}; final static BasicStroke dashed = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f); g2.setStroke(dashed); g2.draw(new RoundRectangle2D.Double(x, y, rectWidth, rectHeight, 10, 10));
|
|
// fill Ellipse2D.Double redtowhite = new GradientPaint(0,0,color.RED,100, 0,color.WHITE); g2.setPaint(redtowhite); g2.fill (new Ellipse2D.Double(0, 0, 100, 50));
|
|
使用Java 2D Stroke 和Paint 类,您可以定义花哨的线类型和填充方式。
线类型由Graphics2D 渲染上下文的stroke 属性定义。要设置stroke 属性,您首先创建一个BasicStroke 对象,然后将它传递到Graphics2D 的setStroke 方法中。
BasicStroke 对象中保存着关于线宽,结合类型,端点风格,短线风格。这些信息在Shape 使用draw 方法渲染时使用。
线宽是线轨迹直角的宽度。线宽在用户坐标系中使用浮点数表示,默认的转换方式是等于一英寸的1/72 。
连接风格是两个线段片段相交时的处理。BasicStroke 支持下面三种相交风格:
端点风格是线段片段端点的装饰。BasicStroke 支持以下三种端点风格:
Dash 风格定义了线段中透明的和不透明的部分。Dash 风格由dash 数组和dash 阶段定义。Dash 数组定义了dash 的模式。数组中的每个元素表示了用户坐标系单元中dash 长度和空白的长度。元素0 表示第一个dash ,元素1 表示第一个空白,以此类推。Dash 阶段是dash 模式的补偿,也使用用户坐标系单元指定。Dash 阶段表示线段的开始应用哪部分dash 模式。
填充模式由Graphics2D 渲染上下文的paint 属性定义。要设置paint 属性,您需要创建一个实现Paint 接口的对象,然后将其传入Graphics2D 的setPaint 方法中。
以下三个类实现了Paint 接口:Color, GradientPaint 和TexturePaint 。
要创建GradientPaint ,你需要指定开始位置和颜色,以及终止位置和颜色。渐变色按比例的在线段连接的两端之间由一种颜色变换成另一种颜色。例如:
TexturePaint 类的模式由BufferedImage 类定义。要创建TexturePaint 对象,您指定包含模式和矩形的图像,其中矩形用来复制和保存模式。下图展示了这种特性: