1  import javax.swing.Timer;
  2  import java.util.ArrayList;
  3  import java.awt.*;
  4  import javax.swing.*;
  5  import java.awt.event.*;
  6  
  7  public class MultipleBallApp extends JApplet {
  8    public MultipleBallApp() {
  9      add(new BallControl());
 10    }
 11  
 12    class BallControl extends JPanel {
 13      private BallPanel ballPanel = new BallPanel();
 14      private JButton jbtSuspend = new JButton("Suspend");
 15      private JButton jbtResume = new JButton("Resume");
 16      private JButton jbtAdd = new JButton("+1");
 17      private JButton jbtSubtract = new JButton("-1");
 18      private JScrollBar jsbDelay = new JScrollBar();
 19  
 20      public BallControl() {
 21        // Group buttons in a panel
 22        JPanel panel = new JPanel();
 23        panel.add(jbtSuspend);
 24        panel.add(jbtResume);
 25        panel.add(jbtAdd);
 26        panel.add(jbtSubtract);
 27  
 28        // Add ball and buttons to the panel
 29        ballPanel.setBorder(
 30          new javax.swing.border.LineBorder(Color.red));
 31        jsbDelay.setOrientation(JScrollBar.HORIZONTAL);
 32        ballPanel.setDelay(jsbDelay.getMaximum());
 33        setLayout(new BorderLayout());
 34        add(jsbDelay, BorderLayout.NORTH);
 35        add(ballPanel, BorderLayout.CENTER);
 36        add(panel, BorderLayout.SOUTH);
 37  
 38        // Register listeners
 39        jbtSuspend.addActionListener(new Listener());
 40        jbtResume.addActionListener(new Listener());
 41        jbtAdd.addActionListener(new Listener());
 42        jbtSubtract.addActionListener(new Listener());
 43        jsbDelay.addAdjustmentListener(new AdjustmentListener() {
 44          @Override
 45          public void adjustmentValueChanged(AdjustmentEvent e) {
 46            ballPanel.setDelay(jsbDelay.getMaximum() - e.getValue());
 47          }
 48        });
 49      }
 50  
 51      class Listener implements ActionListener {
 52        @Override
 53        public void actionPerformed(ActionEvent e) {
 54          if (e.getSource() == jbtSuspend) 
 55            ballPanel.suspend();
 56          else if (e.getSource() == jbtResume) 
 57            ballPanel.resume();
 58          else if (e.getSource() == jbtAdd) 
 59            ballPanel.add();
 60          else if (e.getSource() == jbtSubtract) 
 61            ballPanel.subtract();
 62        }
 63      }
 64    }
 65  
 66    class BallPanel extends JPanel {
 67      private int delay = 10;
 68      private ArrayList<Ball> list = new ArrayList<Ball>();
 69  
 70      // Create a timer with the initial dalay
 71      protected Timer timer = new Timer(delay, new ActionListener() {
 72        @Override /** Handle the action event */
 73        public void actionPerformed(ActionEvent e) {
 74          repaint();
 75        }
 76      });
 77  
 78      public BallPanel() {
 79        timer.start();
 80      }
 81  
 82      public void add() {
 83        list.add(new Ball());
 84      }
 85  
 86      public void subtract() {
 87        if (list.size() > 0)
 88          list.remove(list.size() - 1); // Remove the last ball
 89      }
 90  
 91      @Override
 92      protected void paintComponent(Graphics g) {
 93        super.paintComponent(g);
 94  
 95        for (int i = 0; i < list.size(); i++) {
 96          Ball ball = (Ball)list.get(i); // Get a ball
 97          g.setColor(ball.color); // Set ball color
 98  
 99          // Check boundaries
100          if (ball.x < 0 || ball.x > getWidth()) 
101            ball.dx = -ball.dx;
102  
103          if (ball.y < 0 || ball.y > getHeight()) 
104            ball.dy = -ball.dy;
105  
106          // Adjust ball position
107          ball.x += ball.dx;
108          ball.y += ball.dy;
109          g.fillOval(ball.x - ball.radius, ball.y - ball.radius, 
110            ball.radius * 2, ball.radius * 2);
111        }
112      }
113  
114      public void suspend() {
115        timer.stop(); 
116      }
117  
118      public void resume() {
119        timer.start(); 
120      }
121  
122      public void setDelay(int delay) {
123        this.delay = delay;
124        timer.setDelay(delay);
125      }
126    }
127  
128    class Ball {
129      int x = 0;
130      int y = 0; // Current ball position
131      int dx = 2; // Increment on ball's x-coordinate
132      int dy = 2; // Increment on ball's y-coordinate
133      int radius = 5; // Ball radius
134      Color color = new Color((int)(Math.random() * 256),
135          (int)(Math.random() * 256), (int)(Math.random() * 256));
136    }
137  
138    /** Main method */
139    public static void main(String[] args) {
140      JFrame frame = new JFrame();
141      JApplet applet = new MultipleBallApp();
142      frame.add(applet);
143      frame.setTitle("MultipleBallApp");
144      frame.setLocationRelativeTo(null); // Center the frame
145      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
146      frame.setSize(400, 200);
147      frame.setLocationRelativeTo(null); // Center the frame
148      frame.setVisible(true);
149    }
150  }