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

Create a Java class named ButtonBounce (stored in package program7 ) that implem

ID: 3775673 • Letter: C

Question

Create a Java class named ButtonBounce (stored in package program7) that implements a continuous animation of a Blue Ball bouncing within a bordered JPanel Region. The following GUI should be displayed once the application starts:

The blue circle should be placed near the top of the GUI, and initially does nothing when the GUI is first displayed.

Pressing the “Start” button will start the animation. The ball initially travels in the positive x and positive y direction. The initial x speed (increase in the horizontal) should be 1 and the initial y speed (increase in the vertical) should be 1. The ball is therefore initially travelling at a 45 degree path in the positive x and positive y direction. A mosaic showing the path of the ball is shown below:

Once reaching a boundary (in this case, the ball will reach the rightmost boundary), the ball will collide with the boundary with an elastic (i.e., perfect) collision. Colliding with the rightmost boundary results in the following trajectory:

Note that the change in the x direction is now negative, while y maintains the same positive change.

The ball continues travelling in this current path until it hits the bottom boundary as shown below:

At which the change in y also becomes negated, while the change in x is maintained as previously.

The Collision Rules are given below:

A collision with the left/right boundaries results in negating the change in x

A collision with the top/bottom boundaries results in negating the change in y

ControlPanel Usage

The ControlPanel on the right side of the GUI consists of 4 ScrollBars used for controlling:

The change in x (valid values are between 0 and 49 inclusively)

The change in y (valid values are between 0 and 49 inclusively)

The change in width of the ball (the ball is drawn as an ellipse or oval) – valid values are between 1 and 99 inclusively.

The change in height of the ball (valid values are between 1 and 99 inclusively)

Increasing the x/y values will change the trajectory of the ball. An example of a horizontal trajectory is given below:

Examples of changing the value of the width/height is shown below:

The animation continues until the user presses the “Stop” Button.

The animation must start exactly from the ball’s current location once the user presses the “Start” button.

Explanation / Answer

import java.awt.*; // Using AWT's Graphics and Color
import java.awt.event.*; // Using AWT's event classes and listener interfaces
import javax.swing.*; // Using Swing's components and container

/**
* A Bouncing Ball: Running animation via Swing Timer
*/
@SuppressWarnings("serial")
public class CGBouncingBallSwingTimer extends JFrame {
// Define named-constants
private static final int CANVAS_WIDTH = 640;
private static final int CANVAS_HEIGHT = 480;
private static final int UPDATE_PERIOD = 50; // milliseconds

private DrawCanvas canvas; // the drawing canvas (an inner class extends JPanel)

// Attributes of moving object
private int x = 100, y = 100; // top-left (x, y)
private int size = 250; // width and height
private int xSpeed = 3, ySpeed = 5; // displacement per step in x, y

// Constructor to setup the GUI components and event handlers
public CGBouncingBallSwingTimer() {
canvas = new DrawCanvas();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
this.setContentPane(canvas);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
this.setTitle("Bouncing Ball");
this.setVisible(true);

// Define an ActionListener to perform update at regular interval
ActionListener updateTask = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
update(); // update the (x, y) position
repaint(); // Refresh the JFrame, callback paintComponent()
}
};
// Allocate a Timer to run updateTask's actionPerformed() after every delay msec
new Timer(UPDATE_PERIOD, updateTask).start();
}

// Update the (x, y) position of the moving object
public void update() {
x += xSpeed;
y += ySpeed;
if (x > CANVAS_WIDTH - size || x < 0) {
xSpeed = -xSpeed;
}
if (y > CANVAS_HEIGHT - size || y < 0) {
ySpeed = -ySpeed;
}
}

// Define inner class DrawCanvas, which is a JPanel used for custom drawing
private class DrawCanvas extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // paint parent's background
setBackground(Color.BLACK);
g.setColor(Color.BLUE);
g.fillOval(x, y, size, size); // draw a circle
}
}

// The entry main method
public static void main(String[] args) {
// Run GUI codes in Event-Dispatching thread for thread safety
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CGBouncingBallSwingTimer(); // Let the constructor do the job
}
});
}
}