Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8713053
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T05:15:07+00:00 2026-06-13T05:15:07+00:00

I am trying to write a Java application which draws multiple balls on screen

  • 0

I am trying to write a Java application which draws multiple balls on screen which bounce off of the edges of the frame. I can successfully draw one ball. However when I add the second ball it overwrites the initial ball that I have drawn. The code is:

import java.awt.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

public class Ball extends JPanel implements Runnable {

    List<Ball> balls = new ArrayList<Ball>();   
Color color;
int diameter;
long delay;
private int x;
private int y;
private int vx;
private int vy;

public Ball(String ballcolor, int xvelocity, int yvelocity) {
    if(ballcolor == "red") {
        color = Color.red;
    }
    else if(ballcolor == "blue") {
        color = Color.blue;
    }
    else if(ballcolor == "black") {
        color = Color.black;
    }
    else if(ballcolor == "cyan") {
        color = Color.cyan;
    }
    else if(ballcolor == "darkGray") {
        color = Color.darkGray;
    }
    else if(ballcolor == "gray") {
        color = Color.gray;
    }
    else if(ballcolor == "green") {
        color = Color.green;
    }
    else if(ballcolor == "yellow") {
        color = Color.yellow;
    }
    else if(ballcolor == "lightGray") {
        color = Color.lightGray;
    }
    else if(ballcolor == "magenta") {
        color = Color.magenta;
    }
    else if(ballcolor == "orange") {
        color = Color.orange;
    }
    else if(ballcolor == "pink") {
        color = Color.pink;
    }
    else if(ballcolor == "white") {     
        color = Color.white;
    }
    diameter = 30;
    delay = 40;
    x = 1;
    y = 1;
    vx = xvelocity;
    vy = yvelocity;
}

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.setColor(color);
    g.fillOval(x,y,30,30); //adds color to circle
    g.setColor(Color.black);
    g2.drawOval(x,y,30,30); //draws circle
}

public void run() {
    while(isVisible()) {
        try {
            Thread.sleep(delay);
        } catch(InterruptedException e) {
            System.out.println("interrupted");
        }
        move();
        repaint();
    }
}

public void move() {
    if(x + vx < 0 || x + diameter + vx > getWidth()) {
        vx *= -1;
    }
    if(y + vy < 0 || y + diameter + vy > getHeight()) {
        vy *= -1;
    }
    x += vx;
    y += vy;
}

private void start() {
    while(!isVisible()) {
        try {
            Thread.sleep(25);
        } catch(InterruptedException e) {
            System.exit(1);
        }
    }
    Thread thread = new Thread(this);
    thread.setPriority(Thread.NORM_PRIORITY);
    thread.start();
}

public static void main(String[] args) {
    Ball ball1 = new Ball("red",3,2);
    Ball ball2 = new Ball("blue",6,2);
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().add(ball1);
    f.getContentPane().add(ball2);
    f.setSize(400,400);
    f.setLocation(200,200);
    f.setVisible(true);
    new Thread(ball1).start();
    new Thread(ball2).start();
}
}

I wanted to create a List of balls and then cycle through drawing each of the balls but I’m still having trouble adding both balls to the Content Pane.

Thanks for any help.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T05:15:09+00:00Added an answer on June 13, 2026 at 5:15 am

    With your current approach…

    • The main problem I can see is that you are placing two opaque components on top of each other…actually you may find you’re circumventing one of them for the other…
    • You should be using a null layout manager, otherwise it will take over and layout your balls as it sees fit.
    • You need to ensure that you are controlling the size and location of the ball pane. This means you’ve taken over the role as the layout manager…
    • You need to randomize the speed and location of the balls to give them less chances of starting in the same location and moving in the same location…
    • Only update the Ball within the context of the EDT.
    • You don’t really need the X/Y values, you can use the panels.

    .

    public class AnimatedBalls {
    
        public static void main(String[] args) {
            new AnimatedBalls();
        }
    
        public AnimatedBalls() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException ex) {
                    } catch (InstantiationException ex) {
                    } catch (IllegalAccessException ex) {
                    } catch (UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new Balls());
                    frame.setSize(400, 400);
                    frame.setVisible(true);
                }
            });
        }
    
        public class Balls extends JPanel {
    
            public Balls() {
                setLayout(null);
                // Randomize the speed and direction...
                add(new Ball("red", 10 - (int) Math.round((Math.random() * 20)), 10 - (int) Math.round((Math.random() * 20))));
                add(new Ball("blue", 10 - (int) Math.round((Math.random() * 20)), 10 - (int) Math.round((Math.random() * 20))));
            }
        }
    
        public class Ball extends JPanel implements Runnable {
    
            Color color;
            int diameter;
            long delay;
            private int vx;
            private int vy;
    
            public Ball(String ballcolor, int xvelocity, int yvelocity) {
                if (ballcolor == "red") {
                    color = Color.red;
                } else if (ballcolor == "blue") {
                    color = Color.blue;
                } else if (ballcolor == "black") {
                    color = Color.black;
                } else if (ballcolor == "cyan") {
                    color = Color.cyan;
                } else if (ballcolor == "darkGray") {
                    color = Color.darkGray;
                } else if (ballcolor == "gray") {
                    color = Color.gray;
                } else if (ballcolor == "green") {
                    color = Color.green;
                } else if (ballcolor == "yellow") {
                    color = Color.yellow;
                } else if (ballcolor == "lightGray") {
                    color = Color.lightGray;
                } else if (ballcolor == "magenta") {
                    color = Color.magenta;
                } else if (ballcolor == "orange") {
                    color = Color.orange;
                } else if (ballcolor == "pink") {
                    color = Color.pink;
                } else if (ballcolor == "white") {
                    color = Color.white;
                }
                diameter = 30;
                delay = 100;
    
                vx = xvelocity;
                vy = yvelocity;
    
                new Thread(this).start();
    
            }
    
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g;
    
                int x = getX();
                int y = getY();
    
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(color);
                g.fillOval(0, 0, 30, 30); //adds color to circle
                g.setColor(Color.black);
                g2.drawOval(0, 0, 30, 30); //draws circle
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(30, 30);
            }
    
            public void run() {
    
                try {
                    // Randamize the location...
                    SwingUtilities.invokeAndWait(new Runnable() {
                        @Override
                        public void run() {
                            int x = (int) (Math.round(Math.random() * getParent().getWidth()));
                            int y = (int) (Math.round(Math.random() * getParent().getHeight()));
    
                            setLocation(x, y);
                        }
                    });
                } catch (InterruptedException exp) {
                    exp.printStackTrace();
                } catch (InvocationTargetException exp) {
                    exp.printStackTrace();
                }
    
                while (isVisible()) {
                    try {
                        Thread.sleep(delay);
                    } catch (InterruptedException e) {
                        System.out.println("interrupted");
                    }
    
                    try {
                        SwingUtilities.invokeAndWait(new Runnable() {
                            @Override
                            public void run() {
                                move();
                                repaint();
                            }
                        });
                    } catch (InterruptedException exp) {
                        exp.printStackTrace();
                    } catch (InvocationTargetException exp) {
                        exp.printStackTrace();
                    }
                }
            }
    
            public void move() {
    
                int x = getX();
                int y = getY();
    
                if (x + vx < 0 || x + diameter + vx > getParent().getWidth()) {
                    vx *= -1;
                }
                if (y + vy < 0 || y + diameter + vy > getParent().getHeight()) {
                    vy *= -1;
                }
                x += vx;
                y += vy;
    
                // Update the size and location...
                setSize(getPreferredSize());
                setLocation(x, y);
    
            }
        }
    }
    

    The “major” problem with this approach, is each Ball has it’s own Thread. This is going to eat into your systems resources real quick as you scale the number of balls up…

    A Different Approach

    As started by Hovercraft, you’re better off creating a container for the balls to live in, where the balls are not components but are “virtual” concepts of a ball, containing enough information to make it possible to bounce them off the walls…

    enter image description here

    public class SimpleBalls {
    
        public static void main(String[] args) {
            new SimpleBalls();
        }
    
        public SimpleBalls() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException ex) {
                    } catch (InstantiationException ex) {
                    } catch (IllegalAccessException ex) {
                    } catch (UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Spot");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    Balls balls = new Balls();
                    frame.add(balls);
                    frame.setSize(400, 400);
                    frame.setVisible(true);
    
                    new Thread(new BounceEngine(balls)).start();
    
                }
            });
        }
    
        public static int random(int maxRange) {
            return (int) Math.round((Math.random() * maxRange));
        }
    
        public class Balls extends JPanel {
    
            private List<Ball> ballsUp;
    
            public Balls() {
                ballsUp = new ArrayList<Ball>(25);
    
                for (int index = 0; index < 10 + random(90); index++) {
                    ballsUp.add(new Ball(new Color(random(255), random(255), random(255))));
                }
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                for (Ball ball : ballsUp) {
                    ball.paint(g2d);
                }
                g2d.dispose();
            }
    
            public List<Ball> getBalls() {
                return ballsUp;
            }
        }
    
        public class BounceEngine implements Runnable {
    
            private Balls parent;
    
            public BounceEngine(Balls parent) {
                this.parent = parent;
            }
    
            @Override
            public void run() {
    
                int width = getParent().getWidth();
                int height = getParent().getHeight();
    
                // Randomize the starting position...
                for (Ball ball : getParent().getBalls()) {
                    int x = random(width);
                    int y = random(height);
    
                    Dimension size = ball.getSize();
    
                    if (x + size.width > width) {
                        x = width - size.width;
                    }
                    if (y + size.height > height) {
                        y = height - size.height;
                    }
    
                    ball.setLocation(new Point(x, y));
    
                }
    
                while (getParent().isVisible()) {
    
                    // Repaint the balls pen...
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            getParent().repaint();
                        }
                    });
    
                    // This is a little dangrous, as it's possible
                    // for a repaint to occur while we're updating...
                    for (Ball ball : getParent().getBalls()) {
                        move(ball);
                    }
    
                    // Some small delay...
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                    }
    
                }
    
            }
    
            public Balls getParent() {
                return parent;
            }
    
            public void move(Ball ball) {
    
                Point p = ball.getLocation();
                Point speed = ball.getSpeed();
                Dimension size = ball.getSize();
    
                int vx = speed.x;
                int vy = speed.y;
    
                int x = p.x;
                int y = p.y;
    
                if (x + vx < 0 || x + size.width + vx > getParent().getWidth()) {
                    vx *= -1;
                }
                if (y + vy < 0 || y + size.height + vy > getParent().getHeight()) {
                    vy *= -1;
                }
                x += vx;
                y += vy;
    
                ball.setSpeed(new Point(vx, vy));
                ball.setLocation(new Point(x, y));
    
            }
        }
    
        public class Ball {
    
            private Color color;
            private Point location;
            private Dimension size;
            private Point speed;
    
            public Ball(Color color) {
    
                setColor(color);
    
                speed = new Point(10 - random(20), 10 - random(20));
                size = new Dimension(30, 30);
    
            }
    
            public Dimension getSize() {
                return size;
            }
    
            public void setColor(Color color) {
                this.color = color;
            }
    
            public void setLocation(Point location) {
                this.location = location;
            }
    
            public Color getColor() {
                return color;
            }
    
            public Point getLocation() {
                return location;
            }
    
            public Point getSpeed() {
                return speed;
            }
    
            public void setSpeed(Point speed) {
                this.speed = speed;
            }
    
            protected void paint(Graphics2D g2d) {
    
                Point p = getLocation();
                if (p != null) {
                    g2d.setColor(getColor());
                    Dimension size = getSize();
                    g2d.fillOval(p.x, p.y, size.width, size.height);
                }
    
            }
        }
    }
    

    Because this is driven by a single thread, it is much more scalable.

    You can also check out the images are not loading which is a similar question 😉

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to write an application which uses a lot of java script inside
I am trying to write a java application connecting to server connection channel with
I am trying to write a small Java application that will let me run
I'm trying to write a client-server application in Java with an XML-based protocol. But
I am trying to write a small application using bouncycastle algorithm, from the BouncyCastleProvider.java
I am trying to write a Java program or Hadoop Pig script which will
I'm trying to write an application which will populate an array with random numbers.
I am trying to run a desktop application which is developed in java rmi.
I'm trying to write a pretty simple application which will upload a video to
I am trying to write a distributed application in Java, however the program I

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.