
import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.concurrent.*;
import java.awt.image.*;

public class AnimateThreads extends JPanel {
	
	private ArrayList<Bouncer> objects;
	private ExecutorService threadExecutor;
	private javax.swing.Timer time;
	
	public AnimateThreads(){
		objects = new ArrayList<Bouncer>();
		threadExecutor = Executors.newCachedThreadPool();
		
		
		time = new javax.swing.Timer(25, new ActionListener(){
			public void actionPerformed(ActionEvent e){
				repaint();
			}
		});
		time.start();
		
		addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e){
				Bouncer b = new Bouncer(e.getX(), e.getY(), getWidth(), getHeight());
				objects.add(b);
				
				threadExecutor.execute(b);
				repaint();
			}
		});
		
		
	}

	public void paintComponent(Graphics g){
		super.paintComponent(g);
		Dimension d = getSize();
		BufferedImage buffer = new BufferedImage((int)d.getWidth(),
							 (int)d.getHeight(), BufferedImage.TYPE_INT_ARGB);
		Graphics bg = buffer.getGraphics();
		bg.setColor(Color.BLACK);
		for(Bouncer b: objects){
			b.draw(bg);
		}
		g.drawImage(buffer, 0,0,this);
	}
	
	public static void main(String[] args) {

		JFrame frame = new JFrame("Animate");
		frame.setContentPane(new AnimateThreads());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(500, 500); 
		frame.setVisible(true);

	}

}

class Bouncer  implements Runnable{
	private int x, y, w, h;
	private int dx, dy;
	
	public Bouncer(int x, int y, int w, int h){
		this.x = x;
		this.y = y;
		this.w = w;
		this.h = h;
		dx = 1;
		dy = 1;
	}

	public void draw(Graphics g){
		g.fillOval(x, y, 20, 20);
	}
	
	public void update(){

		if(x < 0 || x >= w)
			dx = -1*dx;
		
		if(y < 0 || y >= h)
			dy = -1*dy;

		x += dx;
		y += dy;
		
	}
	
	public void run(){
		while(true){
			update();
			
			try {
				Thread.sleep(10);
			}
			catch(InterruptedException ie){
				
			}
		}
	}
}
