AnimationMoving picturesThe bouncing ballReview of MVCReview of Observer and ObservableReview of ThreadsTimersUsing a Timer for animationThe Model class, IThe Model class, IIThe Model class, IIIThe View classThe Controller class, IThe Controller class, IIThe Controller class, IIIThe Controller class, IVSummaryThe EndJan 14, 2019Animation2Moving picturesAnimation—making objects that appear to move on the screen—is done by displaying a series of still pictures, one after the other, in rapid successionGenerally you should try for at least 20 pictures/second20 pictures/second is repainting every 50 milliseconds3The bouncing ball“Bouncing ball” is the “Hello World” of animationWe will develop this program using:Model-View-ControllerObserver-ObservableThreadsTimers4Review of MVCMVC stands for Model-View-ControllerThe Model is the actual internal representationIt should be independent of the other classesIt’s handy if this class can extend ObservableThe View (or a View) is a way of looking at or displaying the modelIt’s handy if this class implements ObserverThe Controller provides for user input and modificationThese three components are usually implemented as separate classes (or sets of classes)5Review of Observer and Observablejava.util.Observable is a classWhen it does something that should be observed, it says:setChanged();notifyObservers(); /* or */ notifyObservers(arg);java.util.Observer is an interfaceIt has to register itself with (subscribe to) an Observable:myObservable.addObserver(myObserver);It has to implement:public void update(Observable obs, Object arg)This method is automatically called when observers are notifiedobs is the object being observedIf the Observable did notifyObservers(), arg is null6Review of ThreadsYou can extend the Thread class:class Animation extends Thread {…}Limiting, since you can only extend one classYou must override public void run( )To make it “go”:Animation anim = new Animation( );anim.start( );Or you can implement the Runnable interface:class Animation implements Runnable {…}You must implement public void run( )To make it “go”:Animation anim = new Animation( ); Thread myThread = new Thread(anim);myThread.start( );7TimersA java.util.Timer is used to schedule code for future executionA Timer may:Schedule a one-time execution, orSchedule repeated executions at regular intervalsTimer constructors:Timer()Timer(boolean isDaemon)Timer(String name)Timer(String name, boolean isDaemon)A Timer can keep an application from terminating, unless it is specified as a daemon threadA daemon thread dies if there are no no-daemon threads runningCreate daemon Timer threads with new Timer(true) ornew Timer(name, true)8Using a Timer for animationpublic void schedule(TimerTask task, long delay, long period)Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay (which may be zero)Subsequent executions take place at approximately regular intervals separated by the specified periodTimes are specified in milliseconds (1/1000s of a second)Notice that schedule requires a TimerTask as an argumentTimerTask is an abstract class you must extend and provide apublic void run() methodTimerTask provides an (implemented) public boolean cancel() methodReturns false if there were no scheduled executions to cancel9The Model class, Iclass Model extends Observable { public final int BALL_SIZE = 20; private int xPosition = 0; private int yPosition = 0; private int xLimit, yLimit; private int xDelta = 6; private int yDelta = 4; // methods (on next slide)}10The Model class, II public void setLimits(int xLimit, int yLimit) { this.xLimit = xLimit - BALL_SIZE; this.yLimit = yLimit - BALL_SIZE; } public int getX() { return xPosition; } public int getY() { return yPosition; } public void makeOneStep() { // code for making one step (on next slide) }11The Model class, III public void makeOneStep() { // Do the work xPosition += xDelta; if (xPosition < 0 || xPosition >= xLimit) { xDelta = -xDelta; xPosition += xDelta; } yPosition += yDelta; if (yPosition < 0 || yPosition >= yLimit) { yDelta = -yDelta; yPosition += yDelta; } // Notify observers setChanged(); notifyObservers(); }12The View classimport java.awt.*;import java.util.*;class View extends Panel implements Observer { Model model; View(Model model) { this.model = model; } public void paint(Graphics g) { g.setColor(Color.red); g.fillOval(model.getX(), model.getY(), model.BALL_SIZE, model.BALL_SIZE); } public void update(Observable obs, Object arg) { repaint(); }}13The Controller class, Iimport java.applet.*;import java.awt.*;import java.awt.event.*;import java.util.Timer;import java.util.TimerTask;import javax.swing.*;public class Controller extends JApplet { JPanel buttonPanel = new JPanel(); JButton runButton = new JButton("Run"); JButton stopButton = new JButton("Stop"); Timer timer; Model model = new Model(); View view = new View(model); // View must know about Model14The Controller class, II public void init() { layOutComponents(); attachListenersToComponents(); // Connect model and view model.addObserver(view); } private void layOutComponents() { setLayout(new BorderLayout()); this.add(BorderLayout.SOUTH, buttonPanel); buttonPanel.add(runButton); buttonPanel.add(stopButton); stopButton.setEnabled(false); this.add(BorderLayout.CENTER, view); }15The Controller class, III private void attachListenersToComponents() { runButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { runButton.setEnabled(false); stopButton.setEnabled(true); timer = new Timer(true); timer.schedule(new Strobe(), 0, 40); // 25 times a second } }); stopButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { runButton.setEnabled(true); stopButton.setEnabled(false); timer.cancel(); } }); }16The Controller class, IV private class Strobe extends TimerTask { public void run() {
View Full Document