многопоточность , добавить таймер к анимации

Задание: переделать код так, чтобы анимация рисовала последовательно точки , соответствующие значениям t , возрастающие от 0 до t max. Добавить кнопку , нажатие которой запустит анимацию.

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Line2D;
public class HypotrochoidPanel extends JPanel {
    private final static int PANEL_SIZE_IN_PX = 420;
    private final static Color COLOR = Color.BLACK;
    private final static Color BACKGROUND_COLOR = Color.WHITE;
    private final static int STROKE_WIDTH = 1;
    private final double axesLimit;
    private final int R, r, d;
    public HypotrochoidPanel(int R, int r, int d) {
        this.R = R;
        this.r = r;
        this.d = d;
        setBackground(BACKGROUND_COLOR);
        axesLimit = d + Math.abs(R - r) * 1.05d;
    }
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(PANEL_SIZE_IN_PX, PANEL_SIZE_IN_PX);
    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(COLOR);
        g2.setStroke(new BasicStroke(STROKE_WIDTH));
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        double t = 0d;
        double step = 0.01;
        double tMax = computeTMax();
        while (t < tMax) {
            double xStart = x(t);
            double yStart = y(t);
            double xEnd = x(t+step);
            double yEnd = y(t+step);
            g2.draw(new Line2D.Double(coordinateToPixel(xStart), coordinateToPixel(yStart), coordinateToPixel(xEnd), coordinateToPixel(yEnd)));
            t += step;
        }
    }
    private double x(double t) {
        return (R - r) * Math.cos(t) + d * Math.cos(t * (R - r) / r);
    }
    private double y(double t) {
        return (R - r) * Math.sin(t) - d * Math.sin(t * (R - r) / r);
    }
    private double coordinateToPixel(double c) {
        return PANEL_SIZE_IN_PX / 2d + (PANEL_SIZE_IN_PX / 2d / axesLimit) * c;
    }
    private double computeTMax() {
        return 2 * Math.PI * HypotrochoidUtils.leastCommonMultiple(R, r) / R;
    }
    public static void main(String... args) {
        int R = 7, r = 5, d = 4;
        JFrame frame = new JFrame("Hypotrochoid: R = " + R + ", r = " + r + ", d = " + d);
        frame.add(new HypotrochoidPanel(R, r, d));
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
public class HypotrochoidUtils {
    public static int greatestCommonDivisor(int a, int b) {
        while (b > 0) {
            int c = b;
            b = a % b;
            a = c;
        }
        return a;
    }
    public static int leastCommonMultiple(int a, int b) {
        return a * (b / greatestCommonDivisor(a, b));
    }
}

Ответы (0 шт):