I've created a program which recreates the Queen Ann's Lace fractal. However, when the amount of points that are being plotted increases, the points are plotted way slower. Is there any way to make it so that I only add a point, instead of adding a point and repainting all of the others? I've looked everywhere for an answer, and nothing has made sense to me. An explanation would be very helpful.
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 QueensLaceFractal
{
public static void main(String[] args) { //main method
Dimension d = new Dimension(700, 700);
JFrame theGUI = new JFrame("Queens Lace Fractal");
ColorPanel panel = new ColorPanel(Color.white);
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.setPreferredSize(d);
Container pane = theGUI.getContentPane();
pane.add(panel);
theGUI.pack();
theGUI.setVisible(true);
}
}
class ColorPanel extends JPanel implements MouseMotionListener, MouseListener{ //colorpanel class
private boolean followMouse = true;
private int x, y;
private int seedx, seedy;
private int pointx, pointy;
private int i;
private int dotcounter;
private int newx, newy;
private Random random = new Random();
private javax.swing.Timer timer;
private javax.swing.Timer arraytimer;
private EndPoint[] EP = new EndPoint[8];
private Seed seed;
private Point[] p = new Point[50000];
private Color yellow = new Color(255, 255, 1);
private Color yellowOrange = new Color(255, 195, 0);
private Color orangeRed = new Color(255, 83, 0);
private Color violetRed = new Color(215, 0, 46);
private Color violet = new Color(129, 0, 127);
private Color violetBlue = new Color(44, 48, 156);
private Color blueGreen = new Color(0, 101, 87);
private Color yellowGreen = new Color(85, 171, 0);
public ColorPanel(Color backcolor){
//constructor
setBackground(backcolor);
addMouseListener(this);
addMouseMotionListener(this);
this.setFocusable(true);
seed = new Seed(350, 350, Color.BLACK);
EP[0] = new EndPoint(350, 50, yellow);
EP[1] = new EndPoint(562, 138, yellowOrange);
EP[2] = new EndPoint(650, 350, orangeRed);
EP[3] = new EndPoint(562, 562, violetRed);
EP[4] = new EndPoint(350, 650, violet);
EP[5] = new EndPoint(138, 562, violetBlue);
EP[6] = new EndPoint(50, 350, blueGreen);
EP[7] = new EndPoint(138, 138, yellowGreen);
dotcounter = 0;
i = 0;
timer = new javax.swing.Timer(1, new MoveListener());
arraytimer = new javax.swing.Timer(1, new ArrayTimer());
}
public void paintComponent(Graphics g){
//paints everything on the panel
super.paintComponent(g);
seed.fill(g);
for (int i = 0; i < 8; i++){
EP[i].fill(g);
}
if (followMouse == true){
//seed follows mouse
timer.start();
seed.moveto(x, y);
g.drawString("Seed" ,x + 10, y - 10);
}
else if (followMouse == false){
//begins drawing points
timer.stop();
arraytimer.start();
int n = random.nextInt(9);
newx = pointx;
newy = pointy;
//1 = yellow
//2 = yellowOrange
//3 = orangeRed
//4 = violetRed
//5 = violet
//6 = violetBlue
//7 = blueGreen
//8 = yellowGreen
//9 = black
if(dotcounter <= 14){
if (n == 8){
pointx = newx - 350;
double doublex = (double) pointx;
doublex = doublex * .5;
pointx = (int) Math.round(doublex);
pointx = newx - pointx;
pointy = newy - 350;
double doubley = (double) pointy;
doubley = doubley * .5;
pointy = (int) Math.round(doubley);
pointy = newy - pointy;
p[dotcounter] = new Point(pointx, pointy, seed.getColor());
}
else{
pointx = newx - EP[n].getX();
double doublex = (double) pointx;
doublex = doublex * .75;
pointx = (int) Math.round(doublex);
pointx = newx - pointx;
pointy = newy - EP[n].getY();
double doubley = (double) pointy;
doubley = doubley * .75;
pointy = (int) Math.round(doubley);
pointy = newy - pointy;
p[dotcounter] = new Point(pointx, pointy, EP[n].getColor());
}
}
else if (dotcounter >= 15 && dotcounter < 50000){
if (n == 8){
pointx = newx - 350;
double doublex = (double) pointx;
doublex = doublex * .5;
pointx = (int) Math.round(doublex);
pointx = newx - pointx;
pointy = newy - 350;
double doubley = (double) pointy;
doubley = doubley * .5;
pointy = (int) Math.round(doubley);
pointy = newy - pointy;
p[dotcounter] = new Point(pointx, pointy, seed.getColor());
}
else{
pointx = newx - EP[n].getX();
double doublex = (double) pointx;
doublex = doublex * .75;
pointx = (int) Math.round(doublex);
pointx = newx - pointx;
pointy = newy - EP[n].getY();
double doubley = (double) pointy;
doubley = doubley * .75;
pointy = (int) Math.round(doubley);
pointy = newy - pointy;
p[dotcounter] = new Point(pointx, pointy, EP[n].getColor());
}
}
else{
//stops timer
arraytimer.stop();
}
for (i = 0; i < dotcounter; i++)
{
//draws points 1 by 1
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) {
//gets x and y of the mouse at all times
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 = 350;
pointy = 350;
followMouse = false;
}
else{}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
private class MoveListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//repaints
repaint();
}
}
private class ArrayTimer implements ActionListener{
public void actionPerformed(ActionEvent e){
//calls paintcomponent method and adds 1 to dotcounter
dotcounter++;
repaint();
}
}
}
class EndPoint{
// variables
private int centerX, centerY, radius;
private Color color;
public EndPoint(int x, int y, Color thecolor){
//constructor
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 seed
centerX = xAmount;
centerY = yAmount;
}
public int getX(){
return centerX;
}
public int getY(){
return centerY;
}
public Color getColor(){
return color;
}
}
class Seed{
// variables
private int centerX, centerY, radius;
private Color color;
public Seed(int x, int y, Color thecolor){
//constructor
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 seed
centerX = xAmount;
centerY = yAmount;
}
public int getX(){
return centerX;
}
public int getY(){
return centerY;
}
public Color getColor(){
return color;
}
}
class Point{
// variables
private int centerX, centerY, radius;
private Color color;
public Point(int x, int y, Color thecolor){
//constructor
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, centerY, radius, radius);
g.setColor(oldColor);
}
public void moveto(int xAmount, int yAmount){
//Moves seed
centerX = xAmount;
centerY = yAmount;
}
}
Here is an example of the output, after more than 21k iterations: