So I'm playing around with java GUI. I'm doing a program that bounces a ball when it hits the end of the window. How do I go about updating the secondBall
to update and show its new location? secondBall.action();
does not work. Refer to THIS DOES NOT WORK in the below code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// Ball. This class describes the concept of ball. A ball has a position
// (given by a coordinate (x,y)), a velocity (given by a
// differential (dx,dy)) and a color.
class Ball {
// Default constants (for all instances of Ball)
static int defaultDiameter = 10;
static Color defaultColor = Color.yellow;
static Rectangle defaultBox = new Rectangle(0,0,100,100);
// Position
private int x, y;
// Speed and direction
private int dx, dy;
// Diameter (size)
private int diameter;
// Color
private Color color;
// Bounding rectangular area within which the ball bounces
private Rectangle box;
// Construction of new balls requires position and direction
public Ball( int x0, int y0, int dx0, int dy0 ) {
x = x0;
y = y0;
dx = dx0;
dy = dy0;
color = defaultColor;
diameter = defaultDiameter;
}
// Set new color
public void setColor( Color c ) {
color = c;
}
// Set new bounding rectangular area
public void setBoundingBox( Rectangle r ) {
box = r;
}
// Set new diameter
public void setDiameter(int newDiameter) {
diameter = newDiameter;
}
// Draw a ball on given graphic area
public void paint( Graphics g ) {
// Change to the color of the ball
g.setColor( color.WHITE );
// The ball is represented as a filled circle, i.e. an ellipse (oval)
// with equal height and width
g.fillOval( x, y, diameter, diameter );
}
// Constrain the ball within the rectangular area. Update the speed
// if necessary.
void constrain() {
// Give absolute coordinates of the rectangular area
int x0 = box.x;
int y0 = box.y;
int x1 = x0 + box.width - diameter;
int y1 = y0 + box.height - diameter;
// Change speed and direction if the ball is outside of it
// rectangular area
if (x < x0) {
dx = Math.abs(dx);
}
if (x > x1) {
dx = -Math.abs(dx);
}
if (y < y0) {
dy = Math.abs(dy);
}
if (y > y1) {
dy = -Math.abs(dy);
}
}
// Move the ball with the current direction and speed one step
public void action() {
x = x + dx;
y = y + dy;
constrain();
}
}
// The BallPanel class defines a drawing surface where the balls are drawn. The
// inherits the JPanel class and implements ActionListener. By
// implement ActionListener you can let a Timer with even
// spaces give a 'tick' when updating the panel should be done.
class BallPanel extends JPanel implements ActionListener {
// Width and height
private int width, height;
// A ball
private Ball ball;
private Ball secondBall;
// Timer. Sends a signal every 50 milliseconds to the panel which
// sent along as ActionListener.
private Timer timer = new Timer(50, this);
// Initialize the attributes
public BallPanel(int width, int height) {
// Find out the width and height of the artboard
this.width = width;
this.height = height;
// Create a new ball
ball = new Ball( width / 10, height / 5, 5, 5 );
secondBall = new Ball( width / 10, height / 5, 5, 5 );
// Set the ball's rectangular bounding box
ball.setBoundingBox( new Rectangle( 0, 0, width, height ) );
// Start the timer.
timer.start();
}
// Update (called on repaint, repaint())
public void paintComponent( Graphics g ) {
// Clear the entire drawing surface (with black color)
g.setColor( Color.black );
g.fillRect( 0, 0, getWidth(), getHeight() );
// Draw the ball (on black background)
ball.paint(g);
ball.setDiameter(15);
secondBall.paint(g);
secondBall.setDiameter(10);
}
// When we get a signal from the timer...
public void actionPerformed(ActionEvent e) {
if(width != getWidth() || height != getHeight())
wasResized();
ball.action();// Do whatever is relevant with the ball
// secondBall.action(); THIS DOES NOT WORK
repaint(); // Automatically make another call
// paintComponent()
}
// Called if window resizes
public void wasResized( ) {
//width = newWidth;
// height = newHeight;
ball.setBoundingBox(new Rectangle(0, 0, getWidth(), getHeight()));
}
}
// This class defines the window created by the program. One
// window (JFrame) is created where an instance of BallPanel (the artboard)
// placed.
public class BallWorld extends JFrame {
// Create a panel
private BallPanel panel = new BallPanel (180, 180);
public BallWorld() {
// Add the ball panel to the center of the frame.
Container c = getContentPane();
c.add(panel, BorderLayout.CENTER);
setSize(200, 200); // Frame size.
setLocation(100, 100); // So that the frame does not end up in a corner.
setVisible(true); // Make the frame visible.
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
// This method is started by the Java virtual machine when java is called
// BallWorld
public static void main(String args[]) {
// This command provides better animation in a part
// Olympics. Comment if the ball moves jerkily.
// System.setProperty("sun.java2d.opengl", "true");
BallWorld world = new BallWorld();
}
}
When trying to animate the secondBall
object I just run in to errors.
I tried adding secondBall.action();
right under ball.action();
in the actionPerformed
method.