简单的小重绘

1.当我们改变窗体的大小或者最小化窗体后为什么窗体不消失呢?

原因是画布是在顶级容器中画出来的,而顶级容器(所有的组件)也都是由系统画出来的,窗体组件在改变大小后,原来的窗体就已经不存在了(组件会自动重新绘制,我们自己画的图就会消失),我们看到的窗体是新绘制出来的窗体。

2.怎么解决图形消失的问题呢?

  1.定义图形类,该类用来存储图形的数据。

  2.你每画一个图形,就需要实例化一个图形对象,图形对象就要存储在数组中。

  3.你在哪一个组件上绘制图形,那么就需要重写该组件的重绘(paint)方法,在重绘方法中,将数组中的数据取出,重新再绘制一次。

3.重绘的实现步骤

1.定义一个Shape图形类,定义图形的属性。

2.在DrawFrame类中定义一个Shape类型的数组。

3.将Shape类型的数组传递到DrawListener事件处理类中。

4.在绘制图形的时候,将图形的数据存入到Shape对象中,然后将Shape对象存入到数组中。

5.在DrawFrame类中,重写paint方法,在方法中遍历数组,获取数组中的Shape对象,根据对象的数据绘制图形。

下面是我刚开始写的代码:

package 重绘;

import java.awt.FlowLayout;

import java.awt.Graphics;

import java.awt.Graphics2D;

import javax.swing.JButton;

import javax.swing.JFrame;

/**

 * 定义画图界面类,该类实现JFrame窗体类

 */

public class we extends JFrame {

/**

 *

 */

public static void main(String [] args){

we df = new we();

df.initUI();

}

public void initUI(){

this.setTitle("简单画图");

this.setSize(600, 500);

this.setDefaultCloseOperation(3);

this.setLocationRelativeTo(null);

this.setLayout(new FlowLayout());

JButton butLine = new JButton("直线");

this.add(butLine);

JButton butSharp = new JButton("矩形");

add(butSharp);

JButton butAngle = new JButton("任意多边形");

add(butAngle);

JButton butHair = new JButton("圆");

add(butHair);

this.setVisible(true);

Graphics g = this.getGraphics();

sd dl = new sd();

this.addMouseListener(dl);

dl.setG(g);

butLine.addActionListener(dl);

butSharp.addActionListener(dl);   

butAngle.addActionListener(dl);

butHair.addActionListener(dl);

//3.将Shape类型的数组传递到DrawListener事件处理类中。

dl.setArrayShape(arrayShape);

}

//2.在DrawFrame类中定义一个Shape类型的数组。

public Shape[] arrayShape = new Shape[1000]; //注意不能写在public void initUI(){}里面

/**

 * 5.在DrawFrame类中,重写paint方法,在方法中遍历数组,获取数组中的Shape对象,根据对象的数据绘制图形。

 */

public void paint(Graphics g){

super.paint(g); //super表示调用父类中的paint方法。

Graphics2D g2d = (Graphics2D)g;

for(int i=0;i<arrayShape.length;i++){

Shape shape = arrayShape[i];  //获取Shape对象

if(null != shape){

g.setColor(shape.color);

g2d.setStroke(shape.stroke);

if(shape.type.equals("直线")){

g.drawLine(shape.x1,shape.y1,shape.x2,shape.y2);

}else if(shape.type.equals("圆")){

g.drawOval(shape.x1,shape.y1,shape.x2,shape.y2);

}else if(shape.type.equals("矩形")){

g.drawRect(shape.x1,shape.y1.shape.x2,shape.y2);

}

else if(shape.type.equals("任意多边形")){

g.drawLine(shape.x1,shape.y1,shape.x2,shape.y2);

}

}else{

break;

}

}

}

}   //可以改为:

if(shape.type.equals(“直线")||shape.type.equals("任意多边形")){

g.drawLine(shape.x1,shape.y1,shape.x2,shape.y2);

}else if(shape.type.equals("圆")){

g.drawOval(shape.x1,shape.y1,shape.x2,shape.y2);

}else if(shape.type.equals("矩形")){

g.drawRect(shape.x1,shape.y1.shape.x2,shape.y2);

}

 

 

 

 

 

package 重绘;

import java.awt.BasicStroke;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

 

/**

 * 1.新建一个DrawListener事件处理类,该类实现MouseListener鼠标事件接口,实现接口中的抽象方法。

 */

public class sd implements MouseListener,ActionListener{

 

private int x1,y1,x2,y2;//2.定义四个整数属性,用来存储图形的坐标值

private Graphics g ;//定义画笔画布类的对象名

private String type = "直线";

int count;

int ex, ey;

int sx, sy;

int x,y;

 

 

//向DrawFrame类借Graphics画笔画布对象的方法

public void setG(Graphics gr){

g = gr;

}

 

private Shape[] arrayShape;  //3.将Shape类型的数组传递到DrawListener事件处理类中。

private int index = 0; //3.记录存储的元素个数

// 3.将Shape类型的数组传递到DrawListener事件处理类中。

public void setArrayShape(Shape[] arrayShape){

this.arrayShape = arrayShape;

}

 

/**

     * 当你的鼠标在事件源上发生单击动机时执行的方法(按下和释放必须要在同一个位置上)

     */

    public void mouseClicked(MouseEvent e){

     x1 = e.getX();

y1 = e.getY();

x2 = e.getX();

y2 = e.getY();

if (type.equals("圆")) {

g.drawOval(x1, y1, x2, y2);

Shape shape = new Shape(x1,y1,x2,y2,Color.black,new BasicStroke(1),"圆",sx,sy,ex,ey,count,x,y);  //改成:Shape shape = new Shape(x1,y1,x2,y2,Color.black,new BasicStroke(1),"圆")

     arrayShape[index++] = shape;

     if(index==1000) index = 0;  //如果已经存入了1000个图形,那么index重置为0

}

if (type.equals("矩形")) {

g.drawRect(x1, y1, x2, y2);Shape shape = new Shape(x1,y1,x2,y2,Color.black,new BasicStroke(1),"矩形",sx,sy,ex,ey,count,x,y);  //改成:Shape shape = new Shape(x1,y1,x2,y2,Color.black,new BasicStroke(1),"矩形")

     arrayShape[index++] = shape;

     if(index==1000) index = 0;//如果已经存入了1000个图形,那么index重置为0

}

 

if (type.equals("任意多边形") && count != 0) {// 判断是否已经画完任意多边形的第一条线了

// 获取点击的坐标值

int x = e.getX();

int y = e.getY();

if (e.getClickCount() == 2) {// 判断是双击,图形要闭合

// 使用x,y和ex,ey画闭合的第一条线

g.drawLine(ex, ey, x, y);

g.drawLine(sx, sy, x, y);

count = 0;

Shape shape = new Shape(x,y,sx,sy,Color.black,new BasicStroke(1),"任意多边形",ex,ey,x1,y1,x2,y2,count);  //改成:Shape shape = new Shape(x1,y1,x2,y2,Color.black,new BasicStroke(1),"任意多边形")

 

     arrayShape[index++] = shape;

     if(index==1000) index = 0;  //如果已经存入了1000个图形,那么index重置为0

} else {// 判断不是双击,要画接下来的线

// 根据上一条线的结束点和当前点击的坐标,来绘制直线

g.drawLine(ex, ey, x, y);

Shape shape = new Shape(x,y,ex,ey,Color.black,new BasicStroke(1),"任意多边形",sx,sy,x1,y1,x2,y2,count);  //改成:Shape shape = new Shape(x1,y1,x2,y2,Color.black,new BasicStroke(1),"任意多边形")

     arrayShape[index++] = shape;

     if(index==1000) index = 0;  //如果已经存入了1000个图形,那么index重置为0

// 将当前这条线的结束赋给ex,ey,作为下一条线的起始点

ex = x;

ey = y;

}

}

    

    }

 

    /**

     * 当你的鼠标在事件源上发生按键按下时执行的方法。

     */

    public void mousePressed(MouseEvent e){

     //2.获取按下时的坐标值

     x1 = e.getX();

     y1 = e.getY();

    }

 

    /**

     * 当你的鼠标在事件源上发生按键释放时执行的方法。

     */

    public void mouseReleased(MouseEvent e){

     //2.获取释放时的坐标值

     x2 = e.getX();

     y2 = e.getY();

     if(type.equals("直线")){

     //调用绘制直线的方法

     g.drawLine(x1, y1, x2, y2);

     //4.在绘制图形的时候,将图形的数据存入到Shape对象中,然后将Shape对象存入到数组中。

     Shape shape = new Shape(x1,y1,x2,y2,Color.black,new BasicStroke(1),"直线",sx,sy,ex,ey,count,x,y);   //改成:Shape shape = new Shape(x1,y1,x2,y2,Color.black,new BasicStroke(1),"直线")

     arrayShape[index++] = shape;

     if(index==1000) index = 0;//如果已经存入了1000个图形,那么index重置为0

    

     }

     if (type.equals("任意多边形") && count == 0) {// 判断是否画任意多边形的第一条线

g.drawLine(x1, y1, x2, y2);

Shape shape = new Shape(x1,y1,x2,y2,Color.black,new BasicStroke(1),"任意多边形",sx,sy,ex,ey,count,x,y);

     arrayShape[index++] = shape;

     if(index==1000) index = 0;//如果已经存入了1000个图形,那么index重置为0

// 存储第一条线的起始点

sx = x1;

sy = y1;

// 存储第一条线的结束点

ex = x2;

ey = y2;

count++;// 表示第一条线已经画完了

}

    }

    /**

     * 当你的鼠标进入到事件源时执行的方法。

     */

    public void mouseEntered(MouseEvent e){

    

    }

 

    /**

     * 当你的鼠标离开事件源时执行的方法。

     */

    public void mouseExited(MouseEvent e){

    

    }

    public void actionPerformed(ActionEvent e) {

type = e.getActionCommand();

}

 

}

 

 

package 重绘;

 

import java.awt.BasicStroke;

import java.awt.Color;

import java.awt.Stroke;

 //1.定义一个Shape图形类,定义图形的属性。

public class Shape{  //这种写法在时间复杂度和空间复杂度上市不足的

public int x1, y1, x2, y2,ex,ey,sx,sy;

int count;

int x,y;

public Color color;

public Stroke stroke;

public String type;

   public Shape(){}  //定义Shape对象,后面用于将Shape对象存入到数组中。这一步非常关键,原来就是因为没有写这一句导致画任意多边形的时候定义更多的东西,占用了许多空间.

public Shape(int x1, int y1, int x2, int y2, Color color, Stroke stroke,String type, int ex, int ey, int sx, int sy, int x, int y, int count) {

this.x1 = x1;

this.y1 = y1;

this.x2 = x2;

this.y2 = y2;

    this.ex=ex;

    this.ey=ey;

    this.sx=sx;

    this.sy=sy;

    this.x=x;

    this.y=y;

    this.count=count;

this.color = color;

this.stroke = stroke;

this.type = type;

//这里可以该改成:public Shape(int x1, int y1, int x2,inty2,Color color, Stroke stroke,String type,) {

this.x1 = x1;

this.y1 = y1;

this.x2 = x2;

this.y2 = y2;

      this.color = color;

this.stroke = stroke;

this.type = type;

}

 运行结果:

下面是目前所学的绘制图形的重绘:

/*      1.新建一个DrawListener事件处理类,该类实现MouseListener鼠标事件接口,实现接口中的抽象方法。
  2.定义四个变量,在按下和释放方法中获取按下和释放的坐标值。
  3.定义Grpahics画笔画布类的对象,调用绘制图形的方法来画图。
   我们的组件是画出来的,那么你要在哪一个组件上画图形,那你的画笔画布对象就从这个组件上获取。
  4.实例化DrawListener事件处理类的对象,对象名dl
  5.给事件源窗体对象添加addMouseListener()鼠标监听方法,指定事件处理类对象dl.
 */
package 文雅0604;

import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JButton;
import javax.swing.JFrame;

/**
 * 定义一个画图界面类,该类继承自JFrame窗体类
 */
public class drawJM extends JFrame {
 /**
  *
  */
 private static final long serialVersionUID = 1L;

 /**
  * 程序入口主函数
  */
 public static void main(String[] args) {
  // 实例化窗体类的对象,调用初始化界面的方法
  drawJM df = new drawJM();
  df.initUI();
 }

 // private Shape[] shape = new Shape[100];
 /**
  * 自定义初始化界面的方法
  */
 public void initUI() {
  setTitle("图画");
  setSize(600, 500);
  setDefaultCloseOperation(3);
  setLocationRelativeTo(null);
  setLayout(new FlowLayout());
  JButton butLine = new JButton("直线");
  add(butLine);
  JButton butSharp = new JButton("矩形");
  add(butSharp);
  JButton butAngle = new JButton("任意多边形");
  add(butAngle);
  JButton butHair = new JButton("圆");
  add(butHair);
  JButton b = new JButton("曲线");
  add(b);
  JButton c = new JButton("刷子");
  add(c);
  JButton a = new JButton("橡皮");
  add(a);
  JButton d = new JButton("喷枪");
  add(d);
  JButton f = new JButton("ring");
  add(f);
  JButton h = new JButton("painting");
  add(h);
  JButton i = new JButton("net");
  add(i);
  JButton t = new JButton("tree");
  add(t);
  setVisible(true);
  // 获取窗体上画笔画布对象(注意:必须要在窗体可见之后才能获取画笔画布对象,否则获取的是null)
  Graphics g = getGraphics();
  // 4.实例化DrawListener事件处理类的对象,对象名dl
  drawListener dl = new drawListener();
  // 5.给事件源窗体对象添加addMouseListener()鼠标监听方法,指定事件处理类对象dl.
  addMouseListener(dl);
  addMouseMotionListener(dl);
  // 调用画图Graphics和Shape类
  dl.setGraphics(g);
  //3.将Shape类型的数组传递到DrawListener事件处理类中。
  dl.setArrayShape(arrayShape);
  // 按钮的动作监听,按钮是事件源,也就是说只有当按下按钮才会执行画图的动作,可以参考登录界面的验证登录
  butLine.addActionListener(dl);
  butSharp.addActionListener(dl);
  butAngle.addActionListener(dl);
  butHair.addActionListener(dl);
  b.addActionListener(dl);
  a.addActionListener(dl);
  c.addActionListener(dl);
  d.addActionListener(dl);
  f.addActionListener(dl);
  i.addActionListener(dl);
  h.addActionListener(dl);
  t.addActionListener(dl);

dl.setArrayShape(arrayShape);  //注意:不能遗漏
  
 }
 //2.在DrawFrame类中定义一个Shape类型的数组。
  public Shape[] arrayShape = new Shape[1000];
  
  /**
   *  5.在DrawFrame类中,重写paint方法,在方法中遍历数组,获取数组中的Shape对象,根据对象的数据绘制图形。
   */
  public void paint(Graphics g){
   super.paint(g);//super表示调用父类中的paint方法。
   
   Graphics2D g2d = (Graphics2D)g;
   
   for(int i=0;i<arrayShape.length;i++){
    Shape shape = arrayShape[i];//获取Shape对象
    if(null != shape){
     
     g.setColor(shape.color);
     g2d.setStroke(shape.stroke);
     if(shape.type.equals("直线")||shape.type.equals("任意多边形")||shape.type.equals("ring")||
       shape.type.equals("painting")||shape.type.equals("net")||shape.type.equals("tree")
       ||shape.type.equals("曲线")||shape.type.equals("刷子")||shape.type.equals("橡皮")||
       shape.type.equals("喷枪")){
      g.drawLine(shape.x1, shape.y1, shape.x2, shape.y2);
     }else if(shape.type.equals("圆")){
      g.drawOval(shape.x1,shape. y1, shape.x2, shape.y2);
     }else if(shape.type.equals("矩形")){
      g.drawRect(shape.x1, shape.y1, shape.x2,shape. y2);}
     
    }else{
     break;
    }
   }
  }
}

package 文雅0604;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Random;

public class drawListener implements MouseListener, MouseMotionListener,
  ActionListener {
 private int x1, y1, x2, y2;// 声明四个整数变量,用来记录按下和释放时的坐标值
 public int sx, sy, ex, ey;// 存储任意多边形的起始点坐标和结束点坐标
 public int count = 0;// 记录画的是任意多边形的第几条线
 public int i = 0;
 public int x3, y3, x4, y4;
 public int t, h;
 public int s;
 public int w = 0;
 public int p = 0;
 public int t1, h1, t2, h2, t3, h3, t4, h4;
 public double a, b, c, d, e, f;
 double x = 0, y = 0;
 double q, v;
 int j;
 double x5, y5;
 private Graphics g;// 声明一个画笔画布类的对象名
 private String type;

 // 向DrawFrame借画笔画布类的对象
 public void setGraphics(Graphics gra) {
  // g = gra;// 把gra传给drawFrame中的g
  g = (Graphics2D) gra;// 强制转型
  // 设置画笔抗锯齿
  ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    RenderingHints.VALUE_ANTIALIAS_ON);
 }

 private Shape[] arrayShape;// 3.将Shape类型的数组传递到DrawListener事件处理类中。
 private int index = 0;// 3.记录存储的元素个数

 // 3.将Shape类型的数组传递到DrawListener事件处理类中。
 public void setArrayShape(Shape[] arrayShape) {
  this.arrayShape = arrayShape;
 }

 /**
  * 当你在事件源上发生鼠标点击动作时执行的方法。(在同一个位置上按下并释放才会执行点击)
  */

 public void mouseClicked(MouseEvent e) {
  x1 = e.getX();
  y1 = e.getY();
  x2 = e.getX();
  y2 = e.getY();
  ((Graphics2D) g).setStroke(new BasicStroke(1));

  if (type.equals("圆")) {
   // 调用绘制圆的方法
   g.drawOval(x1, y1, x2, y2);
   Shape shape = new Shape(x1, y1, x2, y2, Color.black,new BasicStroke(1), "圆");
   arrayShape[index++] = shape;
   if (index == 1000)
    index = 0;// 如果已经存入了1000个图形,那么index重置为0
  }

  if (type.equals("矩形")) {
   g.drawRect(x1, y1, x2, y2);
   Shape shape = new Shape(x1, y1, x2, y2, Color.black,new BasicStroke(1), "矩形");
   arrayShape[index++] = shape;
   if (index == 1000)
    index = 0;// 如果已经存入了1000个图形,那么index重置为0
  }
  if (type.equals("任意多边形") && count != 0) {// 判断是否已经画完任意多边形的第一条线了
             // 获取点击的坐标值

   int x = e.getX();
   int y = e.getY();

   if (e.getClickCount() == 2) {// 判断是双击,图形要闭合
           // 使用x,y和ex,ey画闭合的第一条线
    g.drawLine(ex, ey, x, y);
    Shape shape = new Shape(ex, ey, x, y, Color.black,new BasicStroke(1), "任意多边形");
    arrayShape[index++] = shape;
    if (index == 1000)
     index = 0;// 如果已经存入了1000个图形,那么index重置为0
    g.drawLine(sx, sy, x, y);
    Shape shape1 = new Shape(sx, sy, x, y, Color.black,new BasicStroke(1), "任意多边形");
    arrayShape[index++] = shape1;
    if (index == 1000)
     index = 0;// 如果已经存入了1000个图形,那么index重置为0
    count = 0;
   } else {// 判断不是双击,要画接下来的线
     // 根据上一条线的结束点和当前点击的坐标,来绘制直线
    g.drawLine(ex, ey, x, y);
    Shape shape = new Shape(ex, ey, x, y, Color.black,new BasicStroke(1), "任意多边形");
    arrayShape[index++] = shape;
    if (index == 1000)
     index = 0;// 如果已经存入了1000个图形,那么index重置为0
    // 将当前这条线的结束赋给ex,ey,作为下一条线的起始点
    ex = x;
    ey = y;
   }

  }
  if (type.equals("ring")) {
   double u, f;
   if (e.getClickCount() == 2) {// 双击
    double a = 1.40, b = 1.56, c = 1.40, d = -6.56;
    for (int i = 0; i < 100000; i++) {

     u = d * Math.sin(a * x) - Math.sin(b * y);
     f = c * Math.cos(a * x) + Math.cos(b * y);

     int m = (int) (u * 20 + 300);
     int n = (int) (f * 20 + 300);
     g.drawLine(m, n, m, n);
     Shape shape = new Shape(m,n,m,n,Color.black,new BasicStroke(1), "ring");
     arrayShape[this.index++] = shape;
     if (this.index == 1000)
      index = 0;// 如果已经存入了1000个图形,那么index重置为0
     x = u;
     y = f;
    }
    x = 0;
    y = 0;
   } else {
    double a = -2, b = -2, c = -1.2, d = 2;
    for (int i = 0; i < 100000; i++) {
     u = (Math.sin(a * y) - Math.cos(b * x));
     f = (Math.sin(c * x) - Math.cos(d * y));
     int m = (int) (u * 50 + 500);// 乘数控制图形大小,加法控制图形的位置
     int n = (int) (f * 50 + 500);
     g.drawLine(m, n, m, n);
     Shape shape = new Shape(m,n,m,n,Color.black,new BasicStroke(1), "ring");
     arrayShape[this.index++] = shape;
     if (this.index == 1000)
      index = 0;// 如果已经存入了1000个图形,那么index重置为0
     x = u;
     y = f;
    }
    x = 0;
    y = 0;

   }
  }
  if (type.equals("painting")) {
   if (i < 4) {
    // 画四个点
    t = e.getX();
    h = e.getY();
    g.drawLine(t, h, t, h);
    Shape shape = new Shape(t,h,t,h,Color.black,new BasicStroke(1), "painting");
    arrayShape[this.index++] = shape;
    if (this.index == 1000)
     index = 0;// 如果已经存入了1000个图形,那么index重置为0
    // 分别存储四个点
    if (i == 0) {
     t1 = t;
     h1 = h;
    }

    else if (i == 1) {
     t2 = t;
     h2 = h;
    }

    else if (i == 2) {
     t3 = t;
     h3 = h;
    }

    else if (i == 3) {
     t4 = t;
     h4 = h;
    }
    i++;
   } else {
    Random rand = new Random();
    for (j = 0; j < 200000; j++) {
     int s = rand.nextInt(3);
     if (s == 0) {// 如果选中的是A点
      t4 = (t1 + t4) / 2;
      h4 = (h1 + h4) / 2;
     } else if (s == 1) {// 如果选中的是B点
      t4 = (t2 + t4) / 2;
      h4 = (h2 + h4) / 2;
     } else {// 如果选中的是C点
      t4 = (t3 + t4) / 2;
      h4 = (h3 + h4) / 2;
     }
     g.drawLine(t4, h4, t4, h4);
     Shape shape = new Shape(t4,h4,t4,h4,Color.black,new BasicStroke(1), "painting");
     arrayShape[this.index++] = shape;
     if (this.index == 1000)
      index = 0;// 如果已经存入了1000个图形,那么index重置为0
    }
   }
  }

  if (type.equals("net")) {
   System.out.println("   " + x);
   if (e.getClickCount() == 2) {// 双击
    for (w = 0; w < 25000; w++) {
     double a = 0.4, b = 1, c = 0;
     x5 = y - Math.signum(x) * Math.sqrt(Math.abs(b * x - c));
     y5 = a - x;
     int m = (int) (x5 * 150 + 700);
     int n = (int) (y5 * 150 + 400);
     g.drawLine(m, n, m, n);
     Shape shape = new Shape(m,n,m, n,Color.black,new BasicStroke(1), "net");
     arrayShape[this.index++] = shape;
     if (this.index == 1000)
      index = 0;// 如果已经存入了1000个图形,那么index重置为0
     x = x5;
     y = y5;
    }
    x = 0;
    y = 0;

   } else {
    for (w = 0; w < 100000; w++) {
     int a = 1, b = 4, c = 60;
     x5 = y - Math.signum(x) * Math.sqrt(Math.abs(b * x - c));
     y5 = a - x;
     int m = (int) (x5 * 1 + 800);// 乘数控制图形大小,加法控制图形的位置
     int n = (int) (y5 * 1 + 200);
     g.drawLine(m, n, m, n);
     Shape shape = new Shape(m,n,m, n,Color.black,new BasicStroke(1), "net");
     arrayShape[this.index++] = shape;
     if (this.index == 1000)
      index = 0;// 如果已经存入了1000个图形,那么index重置为0
     x = x5;
     y = y5;
    }
    x = 0;
    y = 0;
   }
  }
  if (type.equals("tree")) {
   double x6, y6;
   Random rand = new Random();
   for (int p = 0; p < 10000; p++) {
    int s = rand.nextInt(100);
    if (s < 10) {
     a = 0;
     b = 0;
     c = 0;
     d = (float) 0.16;
     f = 0;
    } else if (s < 18) {
     a = (float) 0.5;
     b = (float) -0.26;
     c = (float) 0.23;
     d = (float) 0.22;
     f = (float) 1.6;
    } else if (s < 26) {
     a = (float) -0.15;
     b = (float) 0.28;
     c = (float) 0.26;
     d = (float) 0.24;
     f = (float) 0.14;
    } else {
     a = (float) 0.35;
     b = (float) 0.04;
     c = (float) -0.04;
     d = (float) 0.85;
     f = (float) 1.6;
    }
    x6 = a * x + b * y;
    y6 = c * x + d * y + f;
    x = x6;
    y = y6;
    g.drawLine((int) (x6 * (-50) + 600), (int) (y6 * (-50) + 300),(int) (x6 * (-50) + 600), (int) (y6 * (-50) + 300));
    // 犯错:g.drawLine((int)(x1*(-50)+300),(int)(y1*(-50)+400),(int)(x1*(-50)+500),(int)(y1*(-50)+500));随机数表示的是无数个点,所以不是
    Shape shape = new Shape((int) (x6 * (-50) + 600), (int) (y6 * (-50) + 300),(int) (x6 * (-50) + 600), (int) (y6 * (-50) + 300),Color.black,new BasicStroke(1), "tree");
    arrayShape[this.index++] = shape;
    if (this.index == 1000)
     index = 0;// 如果已经存入了1000个图形,那么index重置为0
   }
   x = 0;
   y = 0;
  }
 }

 public void mousePressed(MouseEvent e) {
  x1 = e.getX();
  y1 = e.getY();

 }

 /**
  * 当你在事件源上发生鼠标释放动作时执行的方法。
  */
 public void mouseReleased(MouseEvent e) {
  if (type.equals("直线")) {
   // 调用绘制直线的方法
   g.drawLine(x1, y1, x2, y2);
   Shape shape = new Shape(x1, y1, x2, y2, Color.black,new BasicStroke(1), "直线");
   arrayShape[index++] = shape;
   if (index == 1000)
    index = 0;// 如果已经存入了1000个图形,那么index重置为0
  }

  if (type.equals("任意多边形") && count == 0) {// 判断是否画任意多边形的第一条线
   g.drawLine(x1, y1, x2, y2);
   Shape shape = new Shape(x1, y1, x2, y2, Color.black,new BasicStroke(1), "任意多边形");
   arrayShape[index++] = shape;
   if (index == 1000)
    index = 0;// 如果已经存入了1000个图形,那么index重置为0
   // 存储第一条线的起始点
   sx = x1;
   sy = y1;
   // 存储第一条线的结束点
   ex = x2;
   ey = y2;
   count++;// 表示第一条线已经画完了
  }
 }

 public void mouseDragged(MouseEvent e) {
  x2 = e.getX();
  y2 = e.getY();

  if (type.equals("曲线")) {
   g.setColor(Color.green);
   // 设置线条粗细
   ((Graphics2D) g).setStroke(new BasicStroke(5));
   g.drawLine(x1, y1, x2, y2);// 如果写成(x1,x2,y1,y2)就会使画的曲线只能是固定方向的曲线
   g.setColor(Color.BLACK);// 恢复原来的颜色
   Shape shape = new Shape(x1, y1, x2, y2, Color.green,new BasicStroke(5), "曲线");
   arrayShape[index++] = shape;
   if (index == 1000)
    index = 0;// 如果已经存入了1000个图形,那么index重置为0
   x1 = x2;
   y1 = y2;
  }

  if (type.equals("刷子")) {
   g.setColor(Color.pink);
   ((Graphics2D) g).setStroke(new BasicStroke(10));
   g.drawLine(x1, y1, x2, y2);
   Shape shape = new Shape(x1, y1, x2, y2, Color.pink,new BasicStroke(10), "刷子");
   arrayShape[index++] = shape;
   if (index == 1000)
    index = 0;// 如果已经存入了1000个图形,那么index重置为0
   g.setColor(Color.BLACK);// 恢复原来的颜色
   x1 = x2;
   y1 = y2;
  }
  if (type.equals("橡皮")) {
   // 注意要先设置颜色再画
   g.setColor(Color.white);
   ((Graphics2D) g).setStroke(new BasicStroke(30));
   g.drawLine(x1, y1, x2, y2);
   g.setColor(Color.BLACK);// 恢复原来的颜色
   Shape shape = new Shape(x1, y1, x2, y2, Color.white,new BasicStroke(30), "橡皮");
   arrayShape[index++] = shape;
   if (index == 1000)
    index = 0;// 如果已经存入了1000个图形,那么index重置为0
   x1 = x2;
   y1 = y2;
  }
  if (type.equals("喷枪")) {
   x1=e.getX();
   y1=e.getY();//方法一
   // 设置线条粗细
   ((Graphics2D) g).setStroke(new BasicStroke(1));
   Random rand = new Random();// 实例化一个随机数类的对象
   int size = rand.nextInt(50);// 随机决定要画的点数
   for (int i = 0; i < size; i++) {
    // 在0-7之间可以取50次
    int x = rand.nextInt(8);
    int y = rand.nextInt(8);
    g.drawLine(x1 + x, y1 + y, x1 + x, y1 + y);// 不断改变(x1,y1)的坐标值,实现在(x1,y1)的周围画点
    Shape shape = new Shape(x1 + x, y1 + y, x1 + x, y1 + y,Color.black, new BasicStroke(1), "喷枪");
    arrayShape[this.index++] = shape;//一定要区分变量
    if (this.index == 1000)
     this.index = 0;// 如果已经存入了1000个图形,那么index重置为0
    //x1 = x2;
    //y1 = y2;//方法二
    
   }
  }

 }

 public void mouseExited(MouseEvent e) {
 }

 // 实现ActionListener的抽象方法
 public void actionPerformed(ActionEvent e) {
  type = e.getActionCommand();// ActionCommand获取按钮上的文字或者获取事件源对象
 }

 @Override
 public void mouseMoved(MouseEvent e) {
  // TODO Auto-generated method stub

 }

 @Override
 public void mouseEntered(MouseEvent arg0) {
  // TODO Auto-generated method stub

 }

}

package 文雅0604;
import java.awt.Color;
import java.awt.Stroke;
//1.定义一个Shape图形类,定义图形的属性。
public class Shape{
 public int x1, y1, x2, y2;
 public Color color;
 public Stroke stroke;
 public String type; 
 public Shape(){}//定义Shape对象,后面用于将Shape对象存入到数组中。这一步非常关键,原来就是因为没有写这一句导致画任意多边形的时候定义更多的东西,占用了许多空间.
 public Shape(int x1, int y1, int x2, int y2, Color color, Stroke stroke,
   String type) {
  this.x1 = x1;
  this.y1 = y1;
  this.x2 = x2;
  this.y2 = y2; 
  this.color = color;
  this.stroke = stroke;
  this.type = type;
 }
}

 运行结果:

 

 

 

 

时间: 2024-10-03 13:09:53

简单的小重绘的相关文章

DataGridView重绘painting简单实例

private void dataGridViewX1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) { if (e.RowIndex >= 0 && e.ColumnIndex>=0) { Rectangle newRect = new Rectangle(e.CellBounds.X, e.CellBounds.Y, e.CellBounds.Width - 1, e.CellBounds.

css的重排与重绘

一直在做pc页面的部分,由于网速快,看上去css的写法并没有什么影响所以对css的要求也没怎么注意过,最近在做一些手机端的东西,发现真的差好多,特别是再搭配上js效果时一些延迟更是让人接受不了.在这个快餐的时代,确实导致手机端更具有市场,搭乘地铁的时间变成人们浏览新闻,玩游戏,甚至是购物的时间,此时用户应用的设备多数会是手机,而手机与电脑比起来最大的差距就是网速,这对开发者的要求也就提高了,如何能够加快加载减少响应时间就变成了开发者永恒不变的话题.目前虽然有很多的前辈们已经针对这个现状提出了很多

前端必备的浏览器知识(渲染过程、回流和重绘等)

常用哪几种浏览器测试?有哪些浏览器内核(Rendering Engine)? (Q1)浏览器:Chrome,IE,FireFox,Safari,Opera. (Q2)对应内核:Webkit,Trident,Gecko,Webkit,Presto.(国内的浏览器,除了傲游是直接基于Webkit开发的,其他基本都是基于谷歌在webkit上开发的Chromium,当然谷歌自己也是用的Chromium.另外值得的一提的是手机的系统(安卓.苹果)默认浏览器都是基于webkit内核的) 如何理解浏览器内核?

(转)深入理解flash重绘

深入理解Flash Player重绘 Flash Player 会以SWF内容的帧频速度来刷新需要变化的内容,而这个刷新的过程,我们通常称为“重绘(redraw)”,相信即便是初级的菜鸟也知道,只要使用的是Debug版本的Flash Player, 右键菜单里就会有“Show Redraw Regions (显示重绘区域)” 这个选项,当此选项打开的时候,我们就能清楚地看到此刻场景内被重绘的区域. 那么什么情况下会发生重绘呢??1.最常见的是情况就是舞台上的可视组件在形状.位置.状态(alpha

同一个页面多个CALayer重绘的办法

//知识点,CALayer的重绘,-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx 方法,CALayer的渐变色.多个CALayer重绘的方法. //本例是一个,ViewController类,没有继承任何delegate, 也就是说下边的ca1,ca2,ca3的delegate直接设置为self,不用继承像<UITextFieldDelegate>这样的委托.CALyer好像没有委托,直接用就是了.不用搞清楚,直接写就

x01.Weiqi.7: 调整重绘

GitHub 谁方便谁拍,谁重要拍谁.在这个砖头满天飞的时代,一个好的生态显得尤为重要.  红颜小头发,要的很简单. 也许成绝唱,只因鱼心火. 姚贝福娃的离去,除感叹人生无常外,活着做点有意义的事情,同样显得尤为重要. 数年前为学习人工智能,写了围棋程序,却发现其难度超出了我的想象.特将其放到 GitHub 上,希望有人斧正.注意,是斧正,而非小修小改. 调整重绘 窗口大小改变时,棋盘也要作相应的重绘.这个比较简单,我的方法是把 BoardBase 类中的 m_sbSteps 字段改成 publ

页面的重绘与回流及优化

首先要清楚页面呈现的具体过程: 1.  浏览器把获取到的HTML代码解析成1个DOM树,HTML中的每个tag都是DOM树中的1个节点,根节点就是我们常用的document对象.DOM树里包含了所有HTML标签,包括display:none隐藏,还有用JS动态添加的元素等. 2. 浏览器把所有样式(用户定义的CSS和用户代理)解析成样式结构体,在解析的过程中会去掉浏览器不能识别的样式,比如IE会去掉-moz开头的样式,而FF会去掉_开头的样式. 3.DOM Tree 和样式结构体组合后构建ren

【Fanvas技术解密】HTML5 canvas实现脏区重绘

先说明一下,fanvas是笔者在企鹅公司开发的,即将开源的flash转canvas工具. 脏区重绘(dirty rectangle)并不是一门新鲜的技术了,这在最早2D游戏诞生的时候就已经存在. 复杂的术语或概念就不多说,简单说,脏区重绘就是每一帧绘制图形界面的时候,只重新绘制有变化的区域,而不是全屏刷新.很明显,这肯定能带来性能的提升. 举个例子,看下边两个图:   假设这里是动画的连续2帧,那么从第一帧到第二帧,其实变化的只有蝴蝶的区域.那么所谓的脏区就是两个图片的红色框之和,要把上一帧的蝴

css重绘与回流

高性能WEB开发之页面呈现.重绘.回流(1) 2011-04-25 10:11 BearRui BearRui的Blog 字号:T | T 在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类似的. AD:2014WOT全球软件技术峰会北京站 课程视频发布 在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到