Question copied from the book:
(Game: eye-hand coordination) Write a program that displays a circle of radius 10 pixels filled with a random color at a random location on a panel, as shown in Figure 16.28c. When you click the circle, it disappears and a new randomcolor circle is displayed at another random location. After twenty circles are clicked, display the time spent in the panel, as shown in Figure 16.28d.
My solution:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class EyeHandCoordination extends JFrame {
private final int CIRCLE_RADIUS = 10;
private final int TOTAL_CIRCLES = 20;
private RandomCirclePanel panel = new RandomCirclePanel();
public EyeHandCoordination() {
add(panel);
}
public static void main(String[] args) {
EyeHandCoordination frame = new EyeHandCoordination();
frame.setTitle("EyeHandCoordination");
frame.setSize(300, 300);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private class RandomCirclePanel extends JPanel {
private long startTime;
private long endTime;
private int circleX = 0;
private int circleY = 0;
private int currentCircle = 0;
public RandomCirclePanel() {
startTime = System.currentTimeMillis();
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// Check if in circle
if (inCircle(e.getX(), e.getY()) && currentCircle < TOTAL_CIRCLES) {
currentCircle++;
repaint();
}
}
});
}
/** Display circle at a random location **/
private void changeCircleLocation() {
circleX = (int)(Math.random() * (getWidth() - CIRCLE_RADIUS * 2));
circleY = (int)(Math.random() * (getHeight() - CIRCLE_RADIUS * 2));
}
/** Check if inCircle **/
public boolean inCircle(int mouseX, int mouseY) {
if (distanceFromCenterOfCircle(mouseX, mouseY) <= CIRCLE_RADIUS) {
return true;
}
return false;
}
private int distanceFromCenterOfCircle(int x, int y) {
int centerX = circleX + CIRCLE_RADIUS;
int centerY = circleY + CIRCLE_RADIUS;
return (int)(Math.sqrt((centerX - x) * (centerX - x) + (centerY - y) * (centerY - y)));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
changeCircleLocation();
if (currentCircle >= TOTAL_CIRCLES) {
g.setColor(Color.BLACK);
endTime = System.currentTimeMillis();
FontMetrics fm = g.getFontMetrics();
String s = "Time spent: " + ((endTime - startTime) / 1000.0) + " seconds";
g.drawString(s, width / 2 - fm.stringWidth(s) / 2, height / 2 - fm.getAscent());
}
else {
g.setColor(new Color((int)(Math.random() * 256), (int)(Math.random() * 256), (int)(Math.random() * 256)));
g.fillOval(circleX, circleY, CIRCLE_RADIUS * 2, CIRCLE_RADIUS * 2);
}
}
}
}