在之前完成的接口类和实现子类中做如下修改
在接口类中加入
绘制图形函数:public void paint(Graphics g);
接口类 ↓↓↓
package Shape; import java.awt.*; public interface MyShape { //接口类 public abstract double GetArea(); //计算图形面积接口方法 public abstract double GetCircum(); //计算图形周长接口方法 public void paint(Graphics g); //在Applet中绘制图形 }//MyShape类
圆形类 ↓↓↓
package Shape; import java.awt.*; public class MyCircle implements MyShape{ //圆形类 private int circle_x,circle_y; //圆心坐标 private int circle_radius; //半径 public MyCircle(int x,int y,int radius) //构造方法,初始化变量 { circle_x=x; circle_y=y; circle_radius=radius; }//MyCircle public double GetArea() //计算圆面积方法 { return Math.PI*circle_radius*circle_radius; }//GetArea public double GetCircum() //计算圆周长方法 { return 2*Math.PI*circle_radius; }//GetCircum public void paint(Graphics g) //在Applet中绘制圆形 { g.drawOval(circle_x-circle_radius,circle_y-circle_radius,2*circle_radius,2*circle_radius); }//paint }//MyCircle类
三角形类 ↓↓↓
package Shape; import java.awt.*; public class MyTriangle implements MyShape { //三角形类 private int triangle_x1,triangle_y1; //第一个顶点的坐标 private int triangle_x2,triangle_y2; //第二个顶点的坐标 private int triangle_x3,triangle_y3; //第三个顶点的坐标 private double triangle_a,triangle_b,triangle_c; //三条边的长度 public MyTriangle(int x1,int y1,int x2,int y2,int x3,int y3) //构造方法,初始化变量 { triangle_x1=x1; triangle_y1=y1; triangle_x2=x2; triangle_y2=y2; triangle_x3=x3; triangle_y3=y3; triangle_a=Math.sqrt(Math.pow(triangle_x2-triangle_x1,2)+Math.pow(triangle_y2-triangle_y1,2)); triangle_b=Math.sqrt(Math.pow(triangle_x3-triangle_x1,2)+Math.pow(triangle_y3-triangle_y1,2)); triangle_c=Math.sqrt(Math.pow(triangle_x3-triangle_x2,2)+Math.pow(triangle_y3-triangle_y2,2)); }//MyTriangle public double GetArea() //计算三角形面积方法 { double p=(triangle_a+triangle_b+triangle_c)/2; return Math.sqrt(p*(p-triangle_a)*(p-triangle_b)*(p-triangle_c)); }//GetArea public double GetCircum() //计算三角形周长方法 { return triangle_a+triangle_b+triangle_c; }//GetCircum public void paint(Graphics g) //在Applet中绘制三角形 { int[] x=new int[]{triangle_x1,triangle_x2,triangle_x3}; int[] y=new int[]{triangle_y1,triangle_y2,triangle_y3}; g.drawPolygon(x, y, 3); }//paint }//MyTriangle类
正方形类 ↓↓↓
package Shape; import java.awt.*; public class MySquare implements MyShape { //正方形类 private int square_min_x,square_min_y; //正方形左下角顶点坐标 private int square_max_x,square_max_y; //正方形右上角顶点坐标 private int square_a,square_b; //正方形边长 public MySquare(int x1,int y1,int x2,int y2) //构造方法,初始化变量 { square_min_x=x1; square_min_y=y1; square_max_x=x2; square_max_y=y2; square_a=x2-x1; square_b=y2-y1; }//MySquare public double GetArea() //计算正方形面积方法 { return square_a*square_b; }//GetArea public double GetCircum() //计算正方形周长方法 { return 2*(square_a+square_b); }//GetCircum public void paint(Graphics g) //在Applet中绘制正方形 { g.drawRect(square_min_x, square_min_y, square_a, square_b); }//paint }//MySquare类
正五边形类 ↓↓↓
package Shape; import java.awt.*; import Caculate.*; public class MyRegularPentagon implements MyShape { //正五边形类 private int pentagon_center_x,pentagon_center_y; //正五边形中心坐标 private int pentagon_vertex_x,pentagon_vertex_y; //正无边行某顶点坐标 private double distance; //中心到顶点坐标 private double pentagon_side_length; //正五边形边长 public MyRegularPentagon(int center_x,int center_y,int vertex_x,int vertex_y) //构造方法,初始化变量 { pentagon_center_x=center_x; pentagon_center_y=center_y; pentagon_vertex_x=vertex_x; pentagon_vertex_y=vertex_y; distance=Math.sqrt(Math.pow(vertex_x-center_x,2)+Math.pow(vertex_y-center_y,2)); pentagon_side_length=2*distance*(Math.sin(0.2*Math.PI)); }//MyRegularPentagon public double GetArea() //计算正五边形面积方法 { return 0.5*distance*distance*Math.sin(0.4*Math.PI); }//GetArea public double GetCircum() //计算正五边形周长方法 { return 5*pentagon_side_length; }//GetCircum public void paint(Graphics g) //在Applet中绘制正五边形 { double angle=RegularShiftAngle.Cacul_angle(pentagon_center_x, pentagon_center_y, pentagon_vertex_x, pentagon_vertex_y); //计算出所指定顶点和中点之间的线段与屏幕x增大方向所形成的角度 int[] x=new int[5]; int[] y=new int[5]; for (int i = 0; i < 5; i++) { x[i]=(int)(pentagon_center_x + distance * Math.cos(i * 2 * Math.PI / 5 - angle)); y[i]=(int)(pentagon_center_y + distance * Math.sin(i * 2 * Math.PI / 5 - angle)); } g.drawPolygon(x, y, 5); //画五边形 }//paint }//MyRegularPentagon类
其中正五边形用到一个计算所指定顶点与屏幕x增大方向所形成的角度的函数
类代码如下:
package Caculate; public class RegularShiftAngle { //计算出所指定顶点和中点之间的线段与屏幕x增大方向所形成的角度 public static double Cacul_angle(int center_x,int center_y,int vertex_x,int vertex_y) { //可理解为以正五边形中点为原点,以屏幕x增大方向为x轴方向,建立直角坐标系 double angle=0; int tempx=Math.abs(vertex_x-center_x); int tempy=Math.abs(vertex_y-center_y); if(vertex_x==center_x && vertex_y<center_y) angle=0.5 * Math.PI; //90度 else if(vertex_x==center_x && vertex_y>center_y) angle=1.5 * Math.PI; //270度 else if(vertex_x>center_x && vertex_y<=center_y) angle=Math.atan2(tempy, tempx); //第一象限 else if(vertex_x<center_x && vertex_y<=center_y) angle=Math.PI - Math.atan2(tempy, tempx); //第二象限 else if(vertex_x<center_x && vertex_y>center_y) angle=Math.atan2(tempy, tempx) + Math.PI; //第三象限 else if(vertex_x>center_x && vertex_y>center_y) angle=2 * Math.PI - Math.atan2(tempy, tempx); //第四象限 return angle; }//Cacul_angle }//RegularShiftAngle类
在Applet中绘制图形,代码如下:
package Draw; import Shape.*; import java.awt.*; import java.applet.*; public class Applet_drawshape extends Applet { //在Applet中绘制图形 private MyShape[] s=new MyShape[4]; public void init() { setBackground(Color.yellow); //设置背景色为黄色 s[0]=new MyTriangle(150,120,200,20,250,120); //初始化三角形 s[1]=new MySquare(300,20,400,120); //初始化正方形 s[2]=new MyCircle(70,70,50); //初始化圆形 s[3]=new MyRegularPentagon(500,75,500,20);//初始化正五边形 }//init public void paint(Graphics g) { g.setColor(Color.red); //设置前景色为红色 for(MyShape p:s) //依次绘制三角形、正方形、圆形、正五边形 p.paint(g); }//paint }//Applet_drawshape类利用init()方法初始化背景色并初始化各图形坐标及大小;
利用paint()方法调用各图形类中的paint()方法;
类运行时自动调用init()→paint()。
在Frame中绘制图形,代码如下:
package Draw; import Shape.*; import java.awt.*; import javax.swing.*; public class Frame_drawshape { //在Frame中加载绘制好的窗口 public static void main(String[] args) { DrawFrame frame = new DrawFrame(); //建立一个新窗口 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置用户关闭框架时的响应动作 frame.show(); //显示窗口 }//main }//Frame_drawshape类 class DrawFrame extends JFrame { //窗口绘制 public DrawFrame() { setTitle("图形绘制"); setSize(600, 200); Container contentPane = getContentPane(); DrawPanel panel=new DrawPanel(); contentPane.add(panel); //加入DrawPanel的一个对象板 }//构造函数 }//DrawFrame类 class DrawPanel extends JPanel { //在板中绘制图形 public void paintComponent(Graphics g) { super.paintComponent(g); MyShape[] s=new MyShape[4]; s[0]=new MyTriangle(150,120,200,20,250,120); //初始化三角形 s[1]=new MySquare(300,20,400,120); //初始化正方形 s[2]=new MyCircle(70,70,50); //初始化圆形 s[3]=new MyRegularPentagon(500,75,500,20);//初始化正五边形 for(MyShape p:s) //依次在Component中加入三角形、正方形、圆形、正五边形 p.paint(g); }//paintComponent }//DrawPanel类思路:将各图形类绘制在一块板中,在绘制窗口时调用板,在新建窗口中调用绘制好的窗口。
最终程序的文件框架如下:
PS:
① Applet_drawshape.java中没有main方法,所以需手动 右击→运行文件即可;
② 正五边形绘制略复杂,实现方法远不仅此一种(当然这种方法我也没有经过很多数据的调试,读者发现BUG还请告知我),读者也可以自己尝试使用新的方法进行绘制。