Philippe
Philippe

Reputation: 670

Java: Parallel moving balls

I made a program in java that is supposed to create 10 balles appearing and moving randomly, the balls-Threads are supposed to run in parallel, unfortunately the program does not compile. Does anyone know why ? I get the following error for each Threads :

package movement;

import java.applet.Applet;
import java.awt.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;



public class Ball {
    int x;
    int y;
    int radius = 10;
    public Graphics g;
    int dx, dy, n = 0;

    Ball(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void move() {
        Random randomX = new Random();
        Random randomY = new Random();
        Random randomN = new Random();
        paint();

        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            //TODO Auto-generated catch block
            e.printStackTrace();
        }

        x = x + dx;
        y = y + dy;
        dx = (int) (Math.pow(-1, n) * randomX.nextInt(5));
        dy = (int) (Math.pow(-1, n) * randomY.nextInt(5));
        n = randomN.nextInt(10) + 1;
    }

    public void paint() {
        g.setColor(Color.black);
        g.fillOval(x + 100, y + 100, radius, radius);
    }

}

package movement;


class BallMovement implements Runnable {
    private final Ball ball;

    BallMovement(Ball ball) {
        this.ball = ball;
    }

    @Override
    public void run() {
        while (true) {
            ball.move();
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

package movement;

        import java.applet.Applet;
        import java.awt.Color;
        import java.awt.Graphics;
        import java.util.Iterator;
        import java.util.List;
        import java.util.ArrayList;
        import java.util.Random;

public class StartingPoint extends Applet {

    public int startX, startY;
    private static final int nbBalles = 10;
    private static final long serialVersionUID = 1L;
    ArrayList<Ball> BallList = new ArrayList<Ball>();

    @Override
    public void init() {
        for (int i = 0; i < nbBalles; i++) {
            Random randX = new Random();
            Random randY = new Random();
            startX = randX.nextInt(500) + 1;
            startY = randY.nextInt(500) + 1;
            BallList.add(new Ball(startX, startY));
        }
    }

    @Override
    public void start() {
        Iterator<Ball> it = BallList.iterator();
        while (it.hasNext()) {
            Ball ball = it.next();
            Thread thread = new Thread(new BallMovement(ball));
            thread.start();
        }
    }

    @Override
    public void stop() {
        // TODO Auto-generated method stub
    }
}

Exception:

Exception in thread "Thread-5" 
java.lang.NullPointerException at movement.Ball.paint(Ball.java:40) 
at movement.Ball.move(Ball.java:23) 
at movement.BallMovement.run(BallMovement.java:13) 
at java.lang.Thread.run(Thread.java:695) 

Upvotes: 0

Views: 504

Answers (2)

EpicPandaForce
EpicPandaForce

Reputation: 81539

You are supposed to get the Graphics object from the void paint(Graphics g) method of the Applet.

public class StartingPoint extends Applet {

    public int startX, startY;
    private static final int nbBalles = 10;
    private static final long serialVersionUID = 1L;
    ArrayList<Ball> BallList = new ArrayList<Ball>();
    ...

    @Override
    public void paint(Graphics g)
    {
         for(Ball ball : BallList)
         {
             ball.paint(g);
         }
    }
}

and in Ball, change the paint() method to paint(Graphics g).

and don't call paint() from move(), and don't have a Graphics variable in the Ball class.

Upvotes: 1

PeterK
PeterK

Reputation: 1723

I think the problem is this field:

public Graphics g;

when used in this method.

public void paint() {
    g.setColor(Color.black);
    g.fillOval(x + 100, y + 100, radius, radius);
}

Your g field that you are referencing is not initialised.

You can fix it by changing your ball constructor to

Ball(int x, int y, Graphics g) {
    this.x = x;
    this.y = y;
    this.g = g;
}

And then when initialising your ball object, you pass the graphics object from the applet:

BallList.add(new Ball(startX, startY, getGraphics()));

Upvotes: 0

Related Questions