4

In java, how do you drop a ball to a panel in every mouse click? Say I clicked the panel 3 times, so there should be 3 balls bouncing in the panel.

I have this code block:

ball = new Thread() {
    public void run() {
        while (true) { 
            x += speedX;
            y += speedY;
        }
    }
};
ball.start();

repaint();
try {Thread.sleep(100/3);}catch(InterruptedException ex){}

And the method to paint the ball:

public void paintComponent(Graphics ball) {
  super.paintComponent(ball);
  if(clicks>0){
    ball.setColor(Color.BLUE);
    ball.fillOval((int) (x - rad), (int) (y - rad), (int)(2 * rad), (int)(2 * rad));
  }
}

But this thread only drops 1 ball in the panel. I also did try an array of threads but it did not work.

Syche
  • 51
  • 1
  • 2
    Using your current approach, don't. Create a `List` of `balls`, which, when you click the panel, you create a new instance of your `Ball` and add it to the list. You then use something like a Swing `Timer` or (if you really have to) a `Thread`, which updates the state of all the balls in this `List`. You use the same `List` to draw the balls – MadProgrammer Oct 11 '15 at 05:25
  • For [example](http://stackoverflow.com/questions/13022754/java-bouncing-ball/13022788#13022788) and [example](http://stackoverflow.com/questions/14593678/multiple-bouncing-balls-thread-issue/14593761#14593761) – MadProgrammer Oct 11 '15 at 05:26

2 Answers2

1
  1. Obviously you need to keep different (x,y) data for each ball, e.g. have a class Ball with x,y and then List<Ball>

(unless you meant to have them calculated, namely have a single x,y with the balls calculated in some offset to it)

  1. on paintComponent you need to paint all balls, which means some loop of 'fillOval'

  2. your thread(s) need to call 'repaint' after changing x and y. It also needs some 'sleep' otherwise the ball will run too fast.

  3. Regarding the threads, I kind of agree with MadProgrammer: you could have a single thread that iterates over all balls and advances their coordiantes. But it you want several threads (for the exercise, or for better future control) it should work fine, as long as each threads knows which ball it's responsible for. So it's something like

    List<Ball> balls= ...;
    
    Class BallRunnable implements Runnable{
      private Ball ball;
      private JComponent comp; // the one whose paintComponent does fillOval
      public BallRunnable(Ball ball, JComponent comp){
        this.ball=ball;
      }
      public void run(){
         while(true){
            ball.x +=speedX; ball.y+= speedY;
            Thread.sleep(200);
            comp.repaint();
         }
      }
    }
    
Pelit Mamani
  • 2,321
  • 2
  • 13
  • 11
  • Sorry, there seems to be some bug in the code formatting (I always use CTRL+K or the curly braces, and for some reason it's failing now). I hope you can still read the snippet. – Pelit Mamani Oct 11 '15 at 07:03
  • You need to add four extra spaces for a code listing inside an enumeration. Or you can place an empty comment *without indentation* between the enumeration and the code if you want to separate the two. – 5gon12eder Oct 11 '15 at 07:04
1

The behavior of the panel must be defined by setting a MouseListener to the panel to launch a new thread which would create a new ball.

    final JPanel p = new JPanel();
    p.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent e) {
            Thread ball = new Thread() {
                public void run() {
                    while (true) {
                        x += speedX;
                        y += speedY;
                    }
                }
            };
            ball.start();

            p.repaint();
        }

        @Override
        public void mousePressed(MouseEvent e) {

        }

        @Override
        public void mouseReleased(MouseEvent e) {

        }

        @Override
        public void mouseEntered(MouseEvent e) {

        }

        @Override
        public void mouseExited(MouseEvent e) {

        }
    });
deepak marathe
  • 409
  • 3
  • 10