Simple AnimationThe bouncing ballThe Model class, IThe Model class, IIThe Model class, IIIThe Controller class, topThe Controller class: init() IThe Controller class: init() IIThe Controller class: init() IIIThe Controller class, start()The View classThe EndJan 14, 2019Simple Animation2The bouncing ballThe “bouncing ball” is to animation what “Hello world” is to programmingWith a single Thread, we can either......animate the display...provide controls for the display...but we can’t do bothWe will use Observer and Observable to help decouple the model from the viewTo highlight the important portions of the program, I’ll use blue for Thread-relevant code and red for Observer-relevant code3The Model class, I import java.util.Observable;class Model extends Observable implements Runnable { final int BALL_SIZE = 20; int xPosition = 0; int yPosition = 0; int xLimit, yLimit; int xDelta = 6; int yDelta = 4; public boolean running = false; // can be changed from outside public void run() {...} void makeOneStep() {...}}4The Model class, II void makeOneStep() { xPosition += xDelta; if (xPosition < 0) { xPosition = 0; xDelta = -xDelta; } if (xPosition >= xLimit) { xPosition = xLimit; xDelta = -xDelta; } yPosition += yDelta; if (yPosition < 0 || yPosition >= yLimit) { yDelta = -yDelta; yPosition += yDelta; } }Nothing in here is relevant to Threads or Observers5The Model class, III public void run() { while (running) { makeOneStep(); this.setChanged(); this.notifyObservers(); try { Thread.sleep(20); } catch (InterruptedException e) { } }}6The Controller class, top import java.applet.*;import java.awt.*;import java.awt.event.*;import java.util.*; public class Controller extends Applet { Panel buttonPanel = new Panel(); Button runButton = new Button(" Run "); Thread thread; Model model = new Model(); View view = new View(); public void init() {...} public void start() {...}}7The Controller class: init() I public void init() { // Lay out components setLayout (new BorderLayout ()); buttonPanel.add (runButton); this.add (buttonPanel, BorderLayout.SOUTH); this.add (view, BorderLayout.CENTER); // Attach actions to components ... // Tell the View about myself (Controller) and about // the Model ...}8The Controller class: init() II// Attach actions to componentsrunButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (model.running) { model.running = false; runButton.setLabel(" Run "); } else { model.running = true; runButton.setLabel(" Stop "); thread = new Thread(model); thread.start(); }}});Notice that we create a new Thread every time the “Run” button is clicked9The Controller class: init() III// Tell the View about myself (Controller) and about the Modelview.model = model;model.addObserver(view);The View has to know about (have a reference to) the Model in order to display information about itThe Model doesn’t know anything about the ViewThe Observer is added from the outside (here, in the Controller class)The only thing in the Model class about this is that it has to extend ObservableTo be in a separate Thread, the Model has to implement Runnable and supply a public void run() method10The Controller class, start()public void start() { // Getting the view size MUST be done in the start() method model.xLimit = view.getWidth() - model.BALL_SIZE; model.yLimit = view.getHeight() - model.BALL_SIZE;}The Model class needs to know the size of the area that it’s bouncing the ball around inYou can request the size only after the Applet has been initedThe start() method is your first chance for thisIf you want to be able to change the size of the Applet (something you can do from appletviewer, but not from a browser), you need to get the size every time you paintWhen you write an application, you should always allow for the possibility that the user will change the window size11The View class import java.awt.*;import java.util.*; class View extends Canvas implements Observer { Model model; int stepNumber = 0; int position = 50; public void paint(Graphics g) { g.setColor(Color.red); g.fillOval(model.xPosition, model.yPosition, model.BALL_SIZE, model.BALL_SIZE); } public void update(Observable obs, Object arg) { repaint(); }}12The
View Full Document