I have the typical java assignment - Create a JPanel in a JFrame and have balls bounce around. More specifically, each time the user clicks in the window it should generate a ball (random size/color/direction) with an unlimited # of balls. Oh, and each ball should be running in a thread.
I am using an ArrayList to hold the objects. I have a mouseListener that upon a click, instantiates a new ball object. I then create a new thread with that object and call start on it. This all seems to work fine. I put "dummy" JOptionPane pop-ups in various areas to confirm my code was getting there and it appears it is all executing, but no balls ever get drawn, much less drawn over and over to make them move and bounce around the screen.
Any input or suggestions would be much appreciated.
import java.util.Random;
import java.util.ArrayList;
import java.awt.*;
import javax.swing.*;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class BouncingBalls extends JFrame
{
private JPanel ballPrison;
private Random generator = new Random();
private Color bgColor = Color.WHITE;
ArrayList<Balls> ballsList = new ArrayList<Balls>();
private Color ballColor;
private int ballSize;
private int ballCoordinateX;
private int ballCoordinateY;
private int ballDirectionX;
private int ballDirectionY;
public BouncingBalls()
{
super("Bouncing Balls");
ballPrison = new JPanel();
ballPrison.setBackground(bgColor);
add(ballPrison);
ballPrison.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent event)
{
JOptionPane.showMessageDialog (BouncingBalls.this, "Click at " + event.getX() + "," + event.getY(), "Click Registered", JOptionPane.INFORMATION_MESSAGE);
ballsList.add(new Balls(event.getX(), event.getY()));
Thread t = new Thread(ballsList.get(ballsList.size() - 1));
t.start();
}
} );
}
private class DrawJPanel extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
this.setBackground(bgColor);
g.setColor(ballColor);
g.fillOval(ballCoordinateX, ballCoordinateY, ballSize, ballSize);
}
}
private class Balls implements Runnable
{
public Balls(int x, int y)
{
ballColor = new Color(generator.nextInt(256),generator.nextInt(256),
generator.nextInt(256));
ballSize = generator.nextInt(20) + 5;
ballCoordinateX = x;
ballCoordinateY = y;
ballDirectionX = generator.nextInt(8) + 3;
ballDirectionY = generator.nextInt(8) + 3;
}
public void run()
{
/* JOptionPane.showMessageDialog (BouncingBalls.this,
"ballColor = " + ballColor + "\nballSize = " + ballSize + "\nCoordinates = " + ballCoordinateX + "," +
ballCoordinateY + "\nDirections = " + ballDirectionX + "," + ballDirectionX,
"Click Registered", JOptionPane.INFORMATION_MESSAGE);
*/
while(true)
{
move();
repaint();
}
}
public void move()
{
if (ballCoordinateX + ballDirectionX < 0) {
ballDirectionX = ballDirectionX;
} else if (ballCoordinateX + ballDirectionX > getWidth() - ballSize) {
ballDirectionX = -(ballDirectionX);
} else if (ballCoordinateY + ballDirectionY < 0) {
ballDirectionY = ballDirectionY;
} else if (ballCoordinateY + ballDirectionY > getHeight() - ballSize) {
ballDirectionY = -(ballDirectionY);
}
ballCoordinateX = ballCoordinateX + ballDirectionX;
ballCoordinateY = ballCoordinateY + ballDirectionY;
}
}
public static void main (String args[])
{
BouncingBalls ballBox = new BouncingBalls();
ballBox.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ballBox.setSize(500, 500);
ballBox.setLocationRelativeTo(null);
ballBox.setVisible(true);
}
}