Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

// Draw a bouncing ball on the window for 10 seconds. // The ball has a specific

ID: 3632156 • Letter: #

Question

// Draw a bouncing ball on the window for 10 seconds.
// The ball has a specific color, size, location, and direction.
// (x,y) is the upper left corner of the first location.
// Every 10 ms, the ball should move dx pixels horizontally
// and dy pixels vertically.
public static void bounceLoop(DrawingPanel panel, Graphics g, Color c,
int size, int x, int y, int dx, int dy)

Each repetition should do the following:

1. Move the ball to a new position.
2. Update x and y. Specifically, add dx to x and add dy to y.
3. Update dx and dy if needed. The ball needs to change direction
(bounce) when the ball "hits" the side of the window.
4. Pause for 10 ms.

Explanation / Answer

// Header file section

import java.awt.*;

import java.awt.event.*;

import java.util.ArrayList;

import java.util.concurrent.locks.*;

import javax.swing.*;

import javax.swing.border.LineBorder;

public class bounceLoop extends JApplet

{

public static void main(String args[])

{

JFrame frame = new JFrame();

JApplet applet = new bounceLoop();

frame.add(applet);

frame.setTitle("Bouncing Ball");

frame.setLocationRelativeTo(null);

frame.setResizable(false);

frame.setDefaultCloseOperation(3);

frame.setSize(400, 200);

frame.setVisible(true);

}

public bounceLoop()

{

add(new BallControl());

}

// Inner BallControl class.

class BallControl extends JPanel implements ActionListener, AdjustmentListener

{

//Declare variables

private Ball ball;

private JButton jbtSuspend;

private JButton jbtResume;

private JButton jbtAdd;

private JButton jbtSubtract;

private JScrollBar jsbDelay;

// Constructor

public BallControl()

{

//Create a ball panel

ball = new Ball();

//Create Suspend button

jbtSuspend = new JButton("Suspend");

//Create Resume button

jbtResume = new JButton("Resume");

//Create +1 button

jbtAdd = new JButton("+1");

//Create -1 button

jbtSubtract = new JButton("-1");

jsbDelay = new JScrollBar();

//Create panel

JPanel panel = new JPanel();

//Add Suspend button to panel

panel.add(jbtSuspend);

//Add Resume button to panel

panel.add(jbtResume);

//Add +1 button to panel

panel.add(jbtAdd);

//Add -1 button to panel

panel.add(jbtSubtract);

//Add ball and buttons to the panel

ball.setBorder(new LineBorder(Color.red));

jsbDelay.setOrientation(0);

ball.setDelay(jsbDelay.getMaximum());

setLayout(new BorderLayout());

add(jsbDelay, "North");

add(ball, "Center");

add(panel, "South");

jbtSuspend.addActionListener(this);

jbtResume.addActionListener(this);

jbtAdd.addActionListener(this);

jbtSubtract.addActionListener(this);

jsbDelay.addAdjustmentListener(this);

}

class Ball extends JPanel implements Runnable

{

//Declare class

class BallState

{

int x;

int y;

int dx;

int dy;

Color color;

//Constructor

public BallState()

{

x = 0;

y = 0;

dx = 2;

dy = 2;

//Radom values for red,green and blue

int r = (int)(Math.random()*1000)% 256;

int g = (int)(Math.random()*1000)% 256;

int b = (int)(Math.random()*1000)% 256;

color = new Color(r,g,b);

}

}

public void add()

{

list.add(new BallState());

}

//Subtract method

public void subtract()

{

if(list.size() > 0)

list.remove(list.size() - 1);

}

protected void paintComponent(Graphics g)

{

super.paintComponent(g);

//Check boundaries

for(int i = 0; i < list.size(); i++)

{

BallState ball = (BallState)list.get(i);

if(ball.x < radius)

ball.dx = Math.abs(ball.dx);

if(ball.x > getWidth() - radius)

ball.dx = -Math.abs(ball.dx);

if(ball.y < radius)

ball.dy = Math.abs(ball.dy);

if(ball.y > getHeight() - radius)

ball.dy = -Math.abs(ball.dy);

ball.x += ball.dx;

ball.y += ball.dy;

g.setColor(ball.color);

g.fillOval(ball.x - radius,

ball.y-radius,radius*2,radius*2);

}

}

public void run()

{

try

{

while(true)

{

while(!isSuspended)

{

repaint();

Thread.sleep(speed);

}

lock.lock();

suspended.await();

lock.unlock();

}

}

catch(Exception ex)

{

ex.printStackTrace();

}

}

public void resume()

{

lock.lock();

isSuspended = false;

suspended.signalAll();

lock.unlock();

}

public void suspend()

{

lock.lock();

isSuspended = true;

lock.unlock();

}

public void setDelay(int ms)

{

speed = ms;

}

private int speed;

protected Thread timer;

private ArrayList list;

private int x;

private int y;

private int radius;

private int dx;

private int dy;

boolean isSuspended;

Lock lock;

Condition suspended;

public Ball()

{

speed = 10;

timer = new Thread(this);

list = new ArrayList();

x = 0;

y = 0;

radius = 5;

dx = 2;

dy = 2;

isSuspended = false;

lock = new ReentrantLock();

suspended = lock.newCondition();

timer.start();

}

}

public void actionPerformed(ActionEvent e)

{

if(e.getSource() == jbtSuspend)

ball.suspend();

else

if(e.getSource() == jbtResume)

ball.resume();

else

if(e.getSource() == jbtAdd)

ball.add();

else

if(e.getSource() == jbtSubtract)

ball.subtract();

}

public void adjustmentValueChanged (AdjustmentEvent e)

{

ball.setDelay(jsbDelay.getMaximum() – e.getValue());

}

}

}