重新绘制屏幕的麻烦,但不清除以前的形状

时间:2015-02-09 17:38:04

标签: java swing custom-painting

我正在模拟sierpinski三角形的混沌游戏。

我试图画一个新点,而不是清除最后一个点。随着GUI上的点数增加以创建sierpinski三角形图像,绘制点的速度由于for循环而减小。我想在没有for循环的情况下运行这个程序,但每次重绘时,前一点都会清除。

截至目前,我已经制作了这个程序的工作版本,但我希望它更高效。

这是我整个计划的代码。

import javax.swing.*; //JFrame and JPanel
import java.awt.*; //Color and Container
import javax.swing.JOptionPane;
import java.awt.event.*;
import java.util.Scanner;
import java.io.*;
import java.util.Random;
import java.util.ArrayList;
import java.util.List;

/**
 * Write a description of class ChaosGame here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class ChaosGame
{
    public static void main(String[] args) {
        JFrame theGUI = new JFrame("Chaos Game");
        theGUI.setSize(800, 800);
        theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ColorPanel panel = new ColorPanel(Color.white);
        Container pane = theGUI.getContentPane();
        pane.add(panel);
        theGUI.setVisible(true);
    }
}
class ColorPanel extends JPanel implements MouseMotionListener, MouseListener{
    private Random random = new Random();
    private Seed s;
    private Red r;
    private Blue b;
    private Green gr;
    private boolean followMouse = true;
    javax.swing.Timer timer;
    javax.swing.Timer arraytimer;
    private int x, y;
    private int newx, newy;
    private int redx = 100;
    private int redy = 660;
    private int bluex = 700;
    private int bluey = 660;
    private int greenx = 400;
    private int greeny = 140;
    private int pointx, pointy;
    private int seedx, seedy;
    private int i;
    private int dotcounter;
    private Point[] p = new Point[10000];

    public ColorPanel(Color backcolor){
        setBackground(backcolor);
        s = new Seed(400, 400, Color.YELLOW);
        r = new Red(100, 660, Color.RED);
        b = new Blue(700, 660, Color.BLUE);
        gr = new Green(400, 140, Color.GREEN);
        i = 0;
        dotcounter = 0;
        addMouseListener(this);
        addMouseMotionListener(this);
        this.setFocusable(true);
        timer = new javax.swing.Timer(1, new MoveListener());
        arraytimer = new javax.swing.Timer(1, new ArrayTimer());
    }

    public void paintComponent(Graphics g){
        //tells ball what to do when it hits the sides
        super.paintComponent(g);
        r.fill(g);
        b.fill(g);
        gr.fill(g);
        s.fill(g);
        Font font = new Font("Courier", Font.PLAIN, 30);
        g.setFont(font);

        if (followMouse == true){
            timer.start();
            s.moveto(x, y);
            g.drawString("Seed" ,x + 10, y - 10);
        }
        else if (followMouse == false){
            timer.stop();
            arraytimer.start();
            s.moveto(seedx, seedy);
            int n = random.nextInt(3) + 1;
            newx = pointx;
            newy = pointy;
            //1 = red
            //2 = green
            //3 = blue
            if(dotcounter <= 14){
                if (n == 1){
                    pointx = (newx + redx) / 2;
                    pointy = (newy + redy) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.WHITE);
                }
                else if (n == 2){
                    pointx = (newx + greenx) / 2;
                    pointy = (newy + greeny) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.WHITE);
                }
                else if (n == 3){
                    pointx = (newx + bluex) / 2;
                    pointy = (newy + bluey) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.WHITE);
                }
            }
            else if (dotcounter >= 15 && dotcounter < 10000){
                if (n == 1){
                    pointx = (newx + redx) / 2;
                    pointy = (newy + redy) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.RED);
                }
                else if (n == 2){
                    pointx = (newx + greenx) / 2;
                    pointy = (newy + greeny) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.GREEN);
                }
                else if (n == 3){
                    pointx = (newx + bluex) / 2;
                    pointy = (newy + bluey) / 2;
                    p[dotcounter] = new Point(pointx, pointy, Color.BLUE);
                }
            }
            else{
                arraytimer.stop();
            }
            for (i = 0; i < dotcounter; i++)
            { 
                p[i].fill(g);
            }
        }
        g.drawString(""+dotcounter, 600, 60);
    }

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

    @Override
    public void mouseMoved(MouseEvent e) {
        x = e.getX();
        y = e.getY();
    }

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

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

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

    @Override
    public void mousePressed(MouseEvent e){
        if (followMouse == true){
            seedx = x;
            seedy = y;
            pointx = seedx;
            pointy = seedy;
            followMouse = false;
        }
        else{}
    }

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

    private class MoveListener implements ActionListener{
        public void actionPerformed(ActionEvent e){
            repaint();
        }
    }
    private class ArrayTimer implements ActionListener{
        public void actionPerformed(ActionEvent e){
            dotcounter++;
            repaint();
        }
    }
}
class Seed{
    private int centerX, centerY, radius;
    private Color color;
    public Seed(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 4;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}
class Red{
    private int centerX, centerY, radius;
    private Color color;
    public Red(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 4;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}
class Blue{
    private int centerX, centerY, radius;
    private Color color;
    public Blue(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 4;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}
class Green{
    private int centerX, centerY, radius;
    private Color color;
    public Green(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 4;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}
class Point{
    private int centerX, centerY, radius;
    private Color color;
    public Point(int x, int y, Color thecolor){
        centerX = x;
        centerY = y;
        radius = 1;
        color = thecolor;
    }

    public void fill(Graphics g){
        //fills circle
        Color oldColor = g.getColor();
        g.setColor(color);
        g.fillRect(centerX-radius, centerY-radius, radius, radius);
        g.setColor(oldColor);
    }

    public void moveto(int xAmount, int yAmount){
        //Moves ball
        centerX = xAmount;
        centerY = yAmount;
    }
}

1 个答案:

答案 0 :(得分:1)

请查看Custom Painting Approaches以了解执行此操作的两种常用方法:

  1. 每次需要重新绘制组件时,保持一个Object列表以绘制并遍历此列表
  2. 绘制到BufferedImage上,然后重新绘制图像。
  3. 听起来第二种方法就是你在第一种方法遇到性能问题时所需的方法。