I am working on simulation of the chaos game for the sierpinski triangle.
I'm trying to paint a new point, without clearing the last one. As the number of points increases on the GUI to create the sierpinski triangle image, the speed in which points are plotted, decreases because of the for loop. I want to run this program without a for loop, but every time I repaint, the previous point clears.
As of now, I have a working version of this program that I made, but I want it to be more efficient.
Here's my code for the whole program.
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;
}
}
Check out Custom Painting Approaches for the two common ways to do this:
Sounds like the second approach is what you need if you have a performance problem with the first approach.