0

I am recursively drawing a FernFractal and I wanted to make the fern look like it is being animated when the code runs.

public void run() {
        try {
            while(true) {
                componentsDrawn = 0;
                componentsToDraw++;
                this.repaint();
                for (int i = 0; i < FractalTester.speed; i++) {
                    Thread.sleep(100);
                }
            }
        }
        catch (InterruptedException e) {}
    }

^above is my current code that uses the repaint and sleep() to make it look like the fractal is animated, but when I run the code, it just prints out the fractal and there isnt any animation.

import java.awt.Graphics;
import java.util.Scanner;
import java.util.regex.Matcher;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class FernFractal {
    
    public static int MAXDIM = 600;
    public static int speed = 1;
    public static int type = 1;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        JFrame frame = new JFrame("FernBoi");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(MAXDIM, MAXDIM);
        Fern f = new Fern();
        frame.add(f);
        frame.setVisible(true);
        new Thread(f).start();
    }
    
}
class Fern extends JPanel implements Runnable{
    private static final long serialVersionUID = 1L;
    private static int componentsDrawn = 0;
    private static int componentsToDraw = 0;

    @Override
    public void paintComponent(Graphics g) {
        // TODO Auto-generated method stub
        super.paintComponent(g);
        int startX = (int) (FernFractal.MAXDIM * 0.3);
        int startY = (int) (FernFractal.MAXDIM * 0.6);
        int startLen = (int) (FernFractal.MAXDIM * 0.1);
        drawFractal1(g, startX, startY, startLen, (Math.PI/3));
    }
    
    private void drawFractal1(Graphics g, int x1, int y1, int segmentLength, double angle) {

        int currX = x1;
        int currY = y1;
        int nextX = currX + (int) (segmentLength * Math.cos(angle));
        int nextY = currY - (int) (segmentLength * Math.sin(angle));
        // Note that whenever you draw a line, it should be in an if statement
        // like the one below, so that you can progressively render the fractal
        if(segmentLength <= 1) return;

        if (componentsDrawn < componentsToDraw) {
            componentsDrawn++;
            g.drawLine(currX, currY, nextX, nextY);
            //left
            drawFractal1(g, nextX, nextY, (int)(segmentLength*0.6), (angle + ((Math.PI) / 2)) );
            //right
            drawFractal1(g, nextX, nextY, (int)(segmentLength*0.6), (angle - ((Math.PI) / 2)) );
            //center
            drawFractal1(g, nextX, nextY, (int)(segmentLength*0.9), (angle - ((Math.PI) / 36)) );
        }




    }
    
    public void run() {
        try {
            while(true) {
                componentsDrawn = 0;
                componentsToDraw++;
                this.repaint();
                for (int i = 0; i < FractalTester.speed; i++) {
                    Thread.sleep(100);
                }
            }
        }
        catch (InterruptedException e) {}
    }
    
}

^above is my entire code in the FernFractal class. Am I misplacing a method somewhere or is my calculations incorrect somewhere? Could someone please help me figure out why the animation is not working? Much appreciated.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
z.rogerye
  • 1
  • 1
  • 4
  • 2
    Try a Timer -> https://stackoverflow.com/questions/15511282/how-can-i-make-a-java-swing-animation-smoother – Wulf Sep 25 '20 at 05:58
  • I see animation. Although it depends on your FractalTest.speed. With a value of 1it works. That logic doesn't make any sense. You don't need the loop and the sleep value. The sleep value should control the animation speed. Also, you should NOT be using static variables in your Fern class. – camickr Sep 25 '20 at 14:59

0 Answers0