Pages

Wednesday, 1 March 2017

Chapter 30 Exercise 6, Introduction to Java Programming, Tenth Edition Y. Daniel LiangY.

30.6 (Bouncing balls) Rewrite Listing 15.17 BallPane.java using a thread to animate bouncing ball movements.


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

public class Exercise06 extends JApplet {

 private static final long serialVersionUID = 1L;

 public Exercise06() {
  add(new BallControl());
 }

 public static void main(String[] args) {
  Exercise06 applet = new Exercise06();
  JFrame frame = new JFrame();
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  frame.setTitle("Exercise06");
  frame.add(applet, BorderLayout.CENTER);
  frame.setSize(600, 400);
  frame.setLocationRelativeTo(null);
  frame.setVisible(true);
 }

 class BallControl extends JPanel {
  private static final long serialVersionUID = 1L;
  private Ball ball = new Ball();
  private JButton jbtSuspend = new JButton("Suspend");
  private JButton jbtResume = new JButton("Resume");
  private JButton jButton1 = new JButton(" +1 ");
  private JButton jButton2 = new JButton(" -1 ");
  private JButton jButton3 = new JButton(" +++ ");
  private JScrollBar jsbDelay = new JScrollBar();

  public BallControl() {
   // Group buttons in a panel
   JPanel panel = new JPanel();
   panel.add(jbtSuspend);
   panel.add(jbtResume);
   panel.add(jButton1);
   panel.add(jButton2);
   panel.add(jButton3);

   
   // Add ball and buttons to the panel
   ball.setBorder(new javax.swing.border.LineBorder(Color.red));
   jsbDelay.setOrientation(JScrollBar.HORIZONTAL);
   ball.setDelay(jsbDelay.getMaximum());
   setLayout(new BorderLayout());
   add(jsbDelay, BorderLayout.NORTH);
   add(ball, BorderLayout.CENTER);
   add(panel, BorderLayout.SOUTH);

   jButton1.addActionListener(new ActionListener() {    
    @Override
    public void actionPerformed(ActionEvent e) {
     ball.addBall();
    }
   });
   jButton2.addActionListener(new ActionListener() {    
    @Override
    public void actionPerformed(ActionEvent e) {
     ball.removeBall();
    }
   });
   jButton3.addActionListener(new ActionListener() {    
    @Override
    public void actionPerformed(ActionEvent e) {
     for (int i = 0; i < 1000; i++) {
      ball.addBall(); 
     }     
    }
   });
   // Register listeners
   jbtSuspend.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
     ball.suspend();
    }
   });
   jbtResume.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
     ball.resume();
    }
   });
   jsbDelay.addAdjustmentListener(new AdjustmentListener() {
    public void adjustmentValueChanged(AdjustmentEvent e) {
     ball.setDelay(jsbDelay.getMaximum() - e.getValue());
    }
   });
  }
 }

 class OneBall {
  public int x = 0;
  public int y = 0;
  public int dx = 2;
  public int dy = 2;
  public Color color = new Color((int) (Math.random() * 256), (int) (Math.random() * 256), (int) (Math.random() * 256));
  
  public OneBall(int x, int y) {
   this.x = x;
   this.y = y;
   dx = (Math.random() < 0.5 ? 2 : -2);
   dy = (Math.random() < 0.5 ? 2 : -2);
  }
  
  public OneBall() {
   this(0, 0);
  }

 }

 class Ball extends JPanel implements Runnable{

  private static final long serialVersionUID = 1L;

  private int delay = 10;
  private boolean isRunning = true;

  private int radius = 5; // Ball radius
  private ArrayList<OneBall> balls = new ArrayList<>();

  
  public Ball() {
   balls.add(new OneBall());
   Thread thread = new Thread(this);
   thread.start();
  }

   
  public void addBall() {
   balls.add(new OneBall((int)(Math.random() * getWidth()), (int)(Math.random() * getHeight())));
  }
  
  public void removeBall() {
   if (balls.size() > 0) {
    balls.remove(balls.size() - 1);
   }
  }


  @Override
  protected void paintComponent(Graphics g) {
   super.paintComponent(g);

   for (int i = 0; i < balls.size(); i++) {
    g.setColor(balls.get(i).color);
    // Check boundaries
    if (balls.get(i).x < 0 || balls.get(i).x > getWidth())
     balls.get(i).dx *= -1;
    if (balls.get(i).y < 0 || balls.get(i).y > getHeight())
     balls.get(i).dy *= -1;

    // Adjust ball position
    balls.get(i).x += balls.get(i).dx;
    balls.get(i).y += balls.get(i).dy;
    g.fillOval(balls.get(i).x - radius, balls.get(i).y - radius, radius * 2, radius * 2);    
   }
   
  }

  public void suspend() {
   isRunning = false;
  }

  public void resume() {
   isRunning = true;
  }

  public void setDelay(int delay) {
   this.delay = delay;
  }


  @Override
  public void run() {
   try {
    while(true) {
     Thread.sleep(delay);
     if(isRunning) {
      repaint();
     }
    }    
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }

}

No comments:

Post a Comment