user2313498
user2313498

Reputation: 1

Multi-threaded bouncing balls, issue displaying balls

I'm trying to use multithreading to draw balls that bounce around inside a JFrame. I can get the coordinates of each ball to update and print out, but I can't get the balls to display. I'm not very strong in graphics, and I'm not quite sure what I'm missing. I think I need to add each instance of Ball to the panel I have inside my frame, but when I tried that it didn't make a difference. I also have a class used to view the JFrame, that I've omitted. What am I missing here?

Ball

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JPanel;

public class Ball extends JPanel implements Runnable  {
JPanel pan;
private static int radius = 10;
private Color color;
private int xPos;
private int yPos;
private int dx;
private int dy;
Dimension d;

public Ball(JPanel p) {
    Random r = new Random();
    this.pan = p;
    this.d = pan.getSize();
    xPos = r.nextInt(d.width-50)+25;
    yPos = r.nextInt(d.height-50)+25;
    dx = r.nextInt(3)+1;
    dy = r.nextInt(3)+1;
    color = new Color(r.nextInt(255*255*255));
    paintComponent(pan.getGraphics());
}

public void move() {
    xPos += dx;
    yPos += dy;
    if (xPos+radius <= 0 || xPos+radius >= d.width)
        dx = -dx;
    if (yPos+radius <= 0 || yPos+radius >= d.height)
        dy = -dy;
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(color);
    g.fillOval(xPos-radius, yPos-radius, 2*radius, 2*radius);
    g.dispose();
}

public void animate() {
    paintComponent(pan.getGraphics());
    move();
    //pan.validate();//this didn't
    //pan.repaint();// work
    try {
        Thread.sleep(40);
    } catch (InterruptedException e) {}
}

public void run() {
    while(true)
        animate();
}
}

BallTracker

import java.util.ArrayList;

public class BallTracker {
private ArrayList<Ball> balls;

public BallTracker() {
    balls = new ArrayList<Ball>();
}

public void addBall(Ball b) {
    balls.add(b);
    Thread t = new Thread(b);
    t.start();
}
}

BallFrame

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BallFrame extends JFrame {
public static final int WIDTH = 500;
public static final int HEIGHT = 550;
private BallTracker tracker;
private JPanel ballPanel;
private JPanel buttonPanel;

public BallFrame() {
    super("BallFrame");
    tracker = new BallTracker();

    // set up ball panel
    ballPanel = new JPanel();
    ballPanel.setSize(WIDTH, 500);

    // listener to add a new ball to tracker
    class bListener implements ActionListener {
        public void actionPerformed( ActionEvent event ) {
            Ball b = new Ball(ballPanel);
            tracker.addBall(b);

        }
    }

    // set up button panel
    buttonPanel = new JPanel();
    buttonPanel.setSize(WIDTH, 50);
    JButton addBallButton = new JButton();
    addBallButton.setText("Add ball");
    addBallButton.addActionListener(new bListener());
    buttonPanel.add(addBallButton);

    // add panels to frame
    add(buttonPanel, BorderLayout.SOUTH);
    add(ballPanel, BorderLayout.CENTER);
    setSize( WIDTH, HEIGHT );
}
}

Upvotes: 0

Views: 1550

Answers (2)

camickr
camickr

Reputation: 324108

I was mainly looking for issues with the way I am trying to draw here, and why I don't see a ball

  1. The Ball isn't added to any panel.
  2. Even when you do add the ball to the panel, the Ball has no size, so there is nothing to paint.
  3. Even if you did give the panel a size only one Ball would ever show up because you Ball panel is opaque.
  4. Your code is attempting to paint the ball at a location within the ball panel. Instead you should be painting the ball at location (0, 0) within your ball panel and then set the location of the Ball panel relative to the parent container.
  5. The parent container should be using a null layout so you can randomly set the location of your Ball panel.

I'm sure there are other issues as well...

I suggest you forget about multithreading and start with the basics of custom painting and using Timers.

Upvotes: 1

LanternMike
LanternMike

Reputation: 664

It seems your ball extends jpanel and has a paint method, but your ballPanel would need to do the painting and your ball doesn't really seem to need to be a panel at all.

set up ball panel
ballPanel = new JPanel();
ballPanel.setSize(WIDTH, 500);

Upvotes: 1

Related Questions