CSCI2014 Exercises:Composite Design Pattern

Total Page:16

File Type:pdf, Size:1020Kb

CSCI2014 Exercises:Composite Design Pattern

CSCI2014 Software Construction with Java Exercises: Timer, Obserever, & Animation

Exercises: Timer, Observer, &Animation.

Objectives 1) Creating an animation, using Timer Events. Background reading: Horstmann, Big Java, section 9.5 2) Using the java.util.Observer interface and the java.util.Observable classes.

Simple Animations

An animation is created by having a set of states that are actioned in sequence. One way to do this in Java is to use a Timer object. (edited from Sun’s Java2 SDK API documentation) A timer fires one or more action events after a specified delay. For example, an animation object can use a Timer as the trigger for drawing its frames.

Setting up a timer involves creating a Timer object, registering one or more action listeners on it, and starting the timer using the start method. For example, the following code creates and starts a timer that fires an action event once per second (as specified by the first argument to the Timer constructor). The second argument to the Timer constructor specifies a listener to receive the timer's action events. int delay = 1000; //milliseconds ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { //...Perform a task... } } ); Timer t = new Timer(delay, taskPerformer); t.start(); Each Timer has one or more action listeners and a delay (the time between action events). When delay milliseconds have passed, the Timer fires an action event to its listeners. By default, this cycle repeats until the stop method is called. class javax.swing.Timer Constructor public Timer(int delay, ActionListener listener) Creates a Timer that will notify its listeners every delay milliseconds. A selection of Methods… public void addActionListener(ActionListener listener) Adds an action listener to the Timer. public void setDelay(int delay) Sets the Timer's delay, the number of milliseconds between successive action events. public void setInitialDelay(int initialDelay) Sets the Timer's initial delay, which by default is the same as the between-event delay. public void start() Starts the Timer, causing it to start sending action events to its listeners. public void restart() Restarts the Timer, canceling any pending firings and causing it to fire with its initial delay. public void stop() Stops the Timer, causing it to stop sending action events to its listeners. lz/csci2014/Week10Exercises.doc/dec03 Page 1 of 8 CSCI2014 Software Construction with Java Exercises: Timer, Obserever, & Animation

Exercises : Timer

1 Study and execute the program below, which demonstrates the basics of using a timer object. (The program is available as a download from the module website).

1 import java.awt.event.*; 2 import javax.swing.*; 3 4 //------Timer Action Handler------5 class TimerActionHandler implements ActionListener { 6 private int x; 7 8 public TimerActionHandler() { 9 x=0; 10 System.out.println(x); 11 } 12 13 public void actionPerformed(ActionEvent e) { 14 x++; 15 System.out.println(x); 16 } 17 } 18 19 // Main application ------20 21 class TimerTest0 { 22 23 public static void main (String[] arg) { 24 //create the timer and its action handler 25 TimerActionHandler tah = new TimerActionHandler(); 26 int delay = 1000; //milliseconds 27 Timer timer = new Timer(delay, tah); 28 29 //run the timer until the user chooses to stop it. 30 timer.start(); 31 JOptionPane.showMessageDialog(null, "Press OK to stop" ); 32 timer.stop(); 33 } 34 }

2

a) Modify the code so that the actions are performed twice every second.

b) Modify the program so that it counts down.

3 Implement a class TimerButtonPanel which has two buttons “Start” and “Stop”. The class should have a Timer as an attribute, and the action listeners for the buttons should restart and stop the timer. Test the buttons on a GUI. class TimerButtonPanel extends Jpanel { private Timer timer; public TimerButtonPanel(Timer t) { timer = t; ...create the buttons and action listeners... lz/csci2014/Week10Exercises.doc/dec03 Page 2 of 8 CSCI2014 Software Construction with Java Exercises: Timer, Obserever, & Animation

4 The program outlined below improves the structure of the code in exercise 1 by making the ‘counter’ into a separate (data model) class. The model is created in the main application method, and then passed to the timer handler as a parameter. Complete the missing lines of code in theTimerActionHandler class: lines 16, 19, 23, and 24.

35 import java.awt.event.*; 36 import javax.swing.*; 37 38 //------model ------39 class Counter { 40 private int x; 41 public Counter() { x = 0; } 42 public int getCount() { return x; } 43 public void inc() { x++; } 44 public String toString() { return Integer.toString(x); } 45 } 46 47 //------Timer Action Handler------48 //This is the action listener that is triggered by the timer 49 class TimerActionHandler implements ActionListener { 50 //...declare a Counter object...; 51 52 public TimerActionHandler(Counter c) { 53 ...copy c to the counter attribute...; 54 } 55 56 public void actionPerformed(ActionEvent e) { 57 ...increment the counter object...; 58 ...output the counter value...; 59 } 60 } 61 62 /* Main application: creates ------63 - counter (model), 64 - timer and action handler (controller) 65 */ 66 class TimerTest1 { 67 public static void main (String[] arg) { 68 //Create the counter class 69 Counter c = new Counter(); 70 71 //create the timer and its action handler for the counter 72 TimerActionHandler tah = new TimerActionHandler(c); 73 int delay = 1000; //milliseconds 74 Timer timer = new Timer(delay, tah); 75 76 //run the timer until the user chooses to stop it. 77 timer.start(); 78 JOptionPane.showMessageDialog(null, "Press OK to stop" ); 79 timer.stop(); 80 } 81 }

lz/csci2014/Week10Exercises.doc/dec03 Page 3 of 8 CSCI2014 Software Construction with Java Exercises: Timer, Obserever, & Animation

5 Draw a class diagram to illustrate the relationship between the classes and interfaces in the program above: Counter, TimerActionHandler, ActionListener, Timer, and TimerTest1.

lz/csci2014/Week10Exercises.doc/dec03 Page 4 of 8 CSCI2014 Software Construction with Java Exercises: Timer, Obserever, & Animation

Exercises : Observer pattern

The appendix to these exercises lists the methods found in the Observer and Observable classes. It also shows a class diagram to illustrate the essence of the observer pattern. An Observable object maintains a list of Observers. Methods that modify the state of the Observable should normally have two additional statements: setChanged(); - to set a flag that the data has been modified notifyObservers(); - to trigger the update method in the registered Observer objects Both these methods are inherited from the class Observable. The Observer and Observable structure is used in the Model-View-Controller architecture. The Model is an Observable object, and the View is an Observer of trhe model. The advantage of this structure is that the controller does not need to send a message to the view class to refresh itself. This notification is done by the Observable object using the notifyObservers() method.

6 Download and study the TimerTest2.java program to see how the Counter and CounterObserver classes implement the Observer pattern. (A skeleton version is given on the next page). a) Identify the changes that have been made to the TimerActionHandler class compared to the version in TimerTest1. b) Draw a class diagram to show the relationship between the classes.

7 a) Create a GUI CounterPanel that is an Observer of a Counter object. This panel should simply consist of a non-editable TextField to display the counter value. b) Combine the CounterPanel and TimerButtonPanel (see question 3) into a single Frame to produce a GUI so that a user can start and stop the timer and display the value of the counter.

Exercises : Animation

A simple animation can be created by drawing a shape, and moving it across the screen. The position coordinates of the shape are maintained in an object similar to the Counter class. A change in position is triggered by the action handler of a timer. The exercise below builds on the work done so far to produce a simple animation.

8 Repeat question 7(a), but replace the TextField on the CounterPanel with a GraphicsComponent. The paintComponent() method should display a simple shape (e.g. a rectangle) at a position (x, 100). The x- coordinate should be read from the counter value. The update method should call the repaint() method so that the component is redrawn. Choose a suitable delay value for the timer (e.g. 100ms). The effect should be that the shape moves smoothly across the screen. This is the basis of an animation.

9 An alternative to use the counter as an index to a sequence of frames, where each frame stores a picture. I.e. if frame is an array of Pictures, and n is the current value of the counter then the GraphicsComponent displays frame[n]. It is useful to modify the Counter class so that it resets to zero at the end of the sequence so that the frame sequence can repeat. [Note: you could try this as an extension to the Picture Drawing project].

lz/csci2014/Week10Exercises.doc/dec03 Page 5 of 8 CSCI2014 Software Construction with Java Exercises: Timer, Obserever, & Animation

1 ...as before... 2 import java.util.*; 3 4 //------model ------5 class Counter extends Observable { 6 ...as before... 7 public void inc() { 8 x++; 9 setChanged(); 10 notifyObservers(); 11 } 12 ...as before... 13 } 14 15 /*--- This Observer is notified of changes to the Counter.------16 * When a change happens the update method is called, */ 17 class CounterObserver implements Observer { 18 private Counter counter; 19 20 public CounterObserver (Counter c) { 21 counter = c; 22 } 23 24 public void update(Observable obj, Object arg) { 25 System.out.println(counter); 26 } 27 } 28 29 //------Timer Action Handler------30 class TimerActionHandler implements ActionListener { 31 private Counter counter; 32 33 public TimerActionHandler(Counter c) { 34 counter = c; 35 } 36 public void actionPerformed(ActionEvent e) { 37 counter.inc(); 38 } 39 } 40 41 /* Main application: creates the MVC components.------42 - counter (model), 43 - observer (view) 44 - timer and action handler (controller) 45 */ 46 class TimerTest2 { 47 public static void main (String[] arg) { 48 Counter c = new Counter(); //model 49 CounterObserver cObserver = new CounterObserver(c); //view 50 c.addObserver(cObserver); //register observer with counter 51 52 ...as before... 53 javax.swing.Timer timer = new javax.swing.Timer(delay, tah); 54 ...as before... 55 } 56 }

lz/csci2014/Week10Exercises.doc/dec03 Page 6 of 8 CSCI2014 Software Construction with Java Exercises: Timer, Obserever, & Animation

Interface java.util.Observer public interface Observer

A class can implement the Observer interface when it wants to be informed of changes in observable objects.

Methods public abstract void update(Observable o, Object arg) This method is called whenever the observed object is changed. An application calls an observable object's notifyObservers method to have all the object's observers notified of the change. Parameters: o - the observable object. arg - an argument passed to the notifyObservers method.

Java’s Observer Pattern

java.util,Observer GUI

<>

update() update() get model data

display data *

s e

r i

e f i

g

g t

e

i o

s

t

t n

e

d

r

a

s

t

a

w

i

t

h

*

java.util.Observable Data Model

collection of Observers data

addObserver() getData()

setChanged()

notifyObservers()

Observer/Observable Concrete classes structure

lz/csci2014/Week10Exercises.doc/dec03 Page 7 of 8 CSCI2014 Software Construction with Java Exercises: Timer, Obserever, & Animation

Class java.util.Observable public class Observable extends Object

This class represents an observable object, or "data" in the model-view paradigm. It can be subclassed to represent an object that the application wants to have observed.

An observable object can have one or more observers. After an observable instance changes, an application calling the Observable's notifyObservers method causes all of its observers to be notified of the change by a call to their update method.

Constructors public Observable() Construct an Observable with zero Observers

Methods public synchronized void addObserver(Observer o) Adds an observer to the set of observers for this object. public synchronized void deleteObserver(Observer o) Deletes an observer from the set of observers of this object. public void notifyObservers() If this object has changed, as indicated by the hasChanged method, then notify all of its observers and then call the clearChanged method to indicate that this object has no longer changed. Each observer has its update method called with two arguments: this observable object and null. public void notifyObservers(Object arg) If this object has changed, as indicated by the hasChanged method, then notify all of its observers and then call the clearChanged method to indicate that this object has no longer changed. Each observer has its update method called with two arguments: this observable object and the arg argument. public synchronized void deleteObservers() Clears the observer list so that this object no longer has any observers. protected synchronized void setChanged() Indicates that this object has changed. protected synchronized void clearChanged() Indicates that this object has no longer changed, or that it has already notified all of its observers of its most recent change. This method is called automatically by the notifyObservers methods. public synchronized boolean hasChanged() Tests if this object has changed. Returns: true if the setChanged method has been called more recently than the clearChanged method on this object; false otherwise. public synchronized int countObservers() Returns the number of observers of this object. lz/csci2014/Week10Exercises.doc/dec03 Page 8 of 8

Recommended publications