import java.awt.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

// Ball 클래스는 각각의 공 객체를 나타냄
class Ball {
    int x, y, xInc, yInc, diameter;  // 공의 x, y 좌표, 이동 증가량(xInc, yInc), 지름(diameter)
    final Random r = new Random();  // 랜덤 색상을 생성하기 위한 Random 객체
    Color color;  // 공의 색상

    public Ball(int d) {  // 생성자: 공의 초기 위치, 이동량, 지름 및 색상을 초기화
        this.diameter = d;
        // 공의 초기 x, y 좌표를 화면 안에서 무작위로 설정
        x = (int) (Math.random() * (BouncingBall.WIDTH - d) + 3);
        y = (int) (Math.random() * (BouncingBall.HEIGHT - d) + 3);
        // 공의 x, y 이동 증가량을 1~5 사이의 무작위 값으로 설정
        xInc = (int) (Math.random() * 5 + 1);
        yInc = (int) (Math.random() * 5 + 1);
        // 공의 색상을 랜덤으로 설정
        color = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
    }

    public void paint(Graphics g) { 	// 공을 그리는 메소드
        // 공이 화면의 좌우 경계를 벗어나면 x 방향 이동량을 반전
        if (x < 0 || x > (BouncingBall.WIDTH - diameter))
            xInc = -xInc;
        // 공이 화면의 상하 경계를 벗어나면 y 방향 이동량을 반전
        if (y < 0 || y > (BouncingBall.HEIGHT - diameter))
            yInc = -yInc;
        // 공의 위치를 이동
        x += xInc;
        y += yInc;
        // 공을 해당 색상과 크기로 화면에 그림
        g.setColor(color);
        g.fillOval(x, y, diameter, diameter);
    }
}

public class BouncingBall extends JFrame implements ActionListener {
    static final int WIDTH = 600;  // 애플리케이션 창의 폭
    static final int HEIGHT = 200;  // 애플리케이션 창의 높이
    private static final int PERIOD = 10;  // 타이머 간격(밀리초)

    class MyPanel extends JPanel {	  // 공을 담는 패널 클래스
        public Ball basket[] = new Ball[10];  // 10개의 공을 담을 배열

        // 생성자: 공 객체를 10개 생성하여 배열에 저장
        public MyPanel() {
            for (int i = 0; i < 10; i++)
                basket[i] = new Ball((int) (30 + 30 * Math.random())); // 공의 크기를 30~60 사이 무작위로 설정
        }
        public void paintComponent(Graphics g) {  // 패널에 공을 그림
            super.paintComponent(g);  // 부모 클래스의 메소드를 호출하여 패널 초기화
            for (Ball b : basket) {  // 배열에 저장된 모든 공을 그림
                b.paint(g);
            }
        }
    }

    public BouncingBall() {	  // 패널에 공을 그림
        setTitle("Bouncing Ball");  // 프레임 제목 설정
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // 닫기 버튼 클릭 시 프로그램 종료
        Timer timer = new Timer(PERIOD, this); // 타이머 객체 생성 (PERIOD마다 ActionEvent 발생)
        timer.start();  // 타이머 시작
        MyPanel panel = new MyPanel();  // 패널 객체 생성
        panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));  // 패널 크기 설정
        add(panel);  // 패널을 프레임에 추가
        pack();  // 프레임 크기를 내용물에 맞게 조정
        setVisible(true);  // 프레임을 화면에 표시
    }
    // 타이머 이벤트 발생 시 호출(화면 갱신)
    @Override
    public void actionPerformed(ActionEvent evt) {
        repaint(); // 패널을 다시 그림 → 공이 움직이는 효과
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new BouncingBall());  // 애플리케이션 객체 생성
    }
}