import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BouncingPoint {
private static final int HEIGHT = 500;
private static final int WIDTH = 200;
public BouncingPoint() {
init();
}
private void init() {
final JFrame frame = new JFrame("The bouncing Point");
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
PointPanel pp = new PointPanel(WIDTH, HEIGHT);
frame.getContentPane().add(pp);
Thread thread = new Thread(new PointThread(pp));
thread.start();
frame.setVisible(true);
}
public static void main(String[] args) {
new BouncingPoint();
}
public static class PointThread implements Runnable {
private PointPanel pointPanel;
private int speed = 4;
private boolean upwards;
public PointThread(PointPanel panel) {
this.pointPanel = panel;
}
@Override
public void run() {
while (true) {
int height = pointPanel.getHeight();
Rectangle oldRect = pointPanel.getRectabgle();
// change up/down
if (oldRect.getCenterY() < (height / 4)) {
upwards = false;
} else if (!upwards && oldRect.getCenterY() > height - 20) {
upwards = true;
}
Point oldLocation = oldRect.getLocation();
Point newLocation;
if (upwards) {
newLocation = new Point(oldLocation.x, oldLocation.y - speed);
} else {
newLocation = new Point(oldLocation.x, oldLocation.y + speed);
}
Rectangle newrect = new Rectangle(newLocation, oldRect.getSize());
pointPanel.updatePoint(newrect);
try {
// 50 Hz
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@SuppressWarnings("serial")
public static class PointPanel extends JPanel {
final Dimension POINT_SIZE = new Dimension(20, 20);
// actual point
Rectangle rect = new Rectangle(new Point(250, 400), new Dimension(20, 20));
public PointPanel(int width, int height) {
super();
// start point (middle of frame bottom)
rect = new Rectangle(new Point(width / 2 - POINT_SIZE.width / 2, height - POINT_SIZE.height), POINT_SIZE);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillOval(rect.x, rect.y, rect.width, rect.height);
}
public void updatePoint(Rectangle newRect) {
Rectangle updateArea = newRect.union(rect);
rect = newRect;
// repaint the specific area
repaint(updateArea.x, updateArea.y, updateArea.width + 1, updateArea.height + 1);
}
public Rectangle getRectabgle() {
return this.rect;
}
}
}