I have a application where each time you click the add ball button a new randomly colored ball is added to the jpanel. It works fine except that the balls suddenly stop at the same spot. I want them to continue to bounce for a longer period of time instead of like 8 bounces. I cannot seem to figure out what I did wrong. Below is my code:

Code:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;

public class BounceBall{
    
    public static void main(String[] args) {
        
        JFrame frame = new BounceFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;


class BounceFrame extends JFrame {

    private BallCanvas canvas;
    public static final int WIDTH = 450;
    public static final int HEIGHT = 350;

    
    public BounceFrame() {
        setSize(WIDTH, HEIGHT);
        setTitle("BounceThread");
        
        Container contentPane = getContentPane();
        canvas = new BallCanvas();
        contentPane.add(canvas, BorderLayout.CENTER);
        JPanel buttonPanel = new JPanel();
        addButton(buttonPanel, "Add Ball",
                new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                addBall();
            }
        });
        
        addButton(buttonPanel, "Exit",
                new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                System.exit(0);
            }

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;

class BallThread extends Thread {
    
    private BouncingBall b;
    
    public BallThread(BouncingBall aBall) { b = aBall; }
    
    public void run() {
        try {
            for (int i = 1; i <= 1000; i++) {
                b.move();
                sleep(5);
            }
        } catch (InterruptedException exception) {
        }
    }
    
}

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;

class BallCanvas extends JPanel {

    private ArrayList balls = new ArrayList();
    
    public void add(BouncingBall b) {
        balls.add(b);
    }
    
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        for (int i = 0; i < balls.size(); i++) {
            BouncingBall b = (BouncingBall)balls.get(i);
            b.draw(g2);
        }
    }
}

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;

class BouncingBall {
    
    private Component canvas;
    private static final int XSIZE = 15;
    private static final int YSIZE = 15;
    private int x = 0;
    private int y = 0;
    private int dx = 2;
    private int dy = 2;
    
    public BouncingBall(Component c) { canvas = c; }
    
    Color color = getColor();
    
    public void draw(Graphics2D g2) {
        
        g2.setColor(color); 
        g2.fillOval(x,y,30,30);   // adds color to circle
        g2.drawOval(x,y,30,30);   // draws circle
        
    }
    
    public void move() {
        x += dx;
        y += dy;
        if (x < 0) {
            x = 0;
            dx = -dx;
        }
        if (x + XSIZE >= canvas.getWidth()) {
            x = canvas.getWidth() - XSIZE;
            dx = -dx;
        }
        if (y < 0) {
            y = 0;
            dy = -dy;
        }
        if (y + YSIZE >= canvas.getHeight()) {
            y = canvas.getHeight() - YSIZE;
            dy = -dy;
        }
        
        canvas.repaint();
    }
    
    private Color getColor() {
        int rval = (int)Math.floor(Math.random() * 256);
        int gval = (int)Math.floor(Math.random() * 256);
        int bval = (int)Math.floor(Math.random() * 256);
        return new Color(rval, gval, bval);
   }
    
    }
Thanks