COMP 310
Spring 2018

Lec08: Connecting the pieces

Home  Info  Canvas   Java Resources  Eclipse Resources  Piazza

Just like the the "Dem Bones" (Dry Bones) song, an OO system is all about connecting the "bones" of our system together.  Each little object is a self-contained, autonomous entity that by itself, doesn't do much.  The macroscopic behavior of the whole system arises from the interconnections and interactions between the objects.   Sometimes it is difficult to understand what an OO system does by simply looking at the lines of code.   Someone one said that "an OO program takes place between the lines of code". 

The Dispatcher as an encapsulation of the Observer-Observable pattern

The process of notifying all the balls to update is an example of the Observer-Observable design pattern because a common, central entity (Observable) is sending out the same message to a set of objects (Observers).

Why do we need a Dispatcher object?

Conclusion: The updating (dispatching) process must be decoupled from the rest of the system.  When the balls need to be updated, the system (model) should delegate to an encapsulated entity, i.e. another object, the Dispatcher, to perform the process of notifying every ball to update.

The above process is an approach called "top-down" programming.   Notice that we focussed on what we needed to have happen, not on how we were going to implement it; a high level, "view-from-the-top".      This is a very useful approach in programming because, as we see here, in the end we might never need to worry about how certain pieces are implemented because that implementation was done by someone else, such as in a supplied library.   The Observable class in the java.util package (with a little help to make it more convenient) already does what we need to have happen, namely dispatch a message out to multiple recipients.

Top-down programming can be a little uncomfortable at first because you seem to be relying on things whose implementations are unknown, but the rewards are well worth the effort of learning how to do it.

Paint process:

  1. Timer queues its ActionListener event into the GUI event loop at the appropriate time and the event gets processed.
  2. ActionListener.actionPerformed calls repaint on JPanel used as the canvas (via adapters and/or call through a method of hte view)
  3. The repaint event gets queued onto Java GUI event loop.
  4. When the repaint event gets processed, the Java GUI system calls paintComponent of the display canvas
  5. paintComponent calls the dispatcher's updateAll (though not necessarily directly, i.e. via adapaters and/or method of the model).   Be sure to pass the Graphics object!
  6. The dispatcher calls the update method of each ball and thus every ball gets updated (move, bounce, update state and paint).

Bouncing Balls

The problem with a discrete simulation such as ours, where the objects are moved in discrete jumps from spot to spot, is that objects (balls, here) could end up in the wrong position.    For instance, if we want the balls to bounce off the walls, the discrete nature of the calculation means that we can never detect the exact moment when the ball just contacts the wall.   Instead, we don't know that the ball needs to bounce off the wall until after the ball is past the wall, going up, down, left or right, depending on which wall.

Bouncing off a wall is fundamentally just the negation of the component of the velocity perpendicular to the wall, but the discrete nature of the simulation forces us to also correct the position of the ball.

How do you tell if the ball is past the wall?   

Once we have detected that the ball is past the wall, we have to reposition the ball back to where it should have been.   The HW02 page describes a simple mathematical model to easily calculate the desired location of the ball given its current location, the location of the wall and the radius of the ball.


Dynamic class loading

The supplied dynamic class loading code takes a "fully qualified class name"  (package+class name) and returns an instantiated object.

Ball creation sequence:

  1. Click "Make Ball" button
  2. Call actionPerformed of the listener takes the text for a text field and sends it to the model, requesting that a ball be made using that class name.
  3. Model uses dynamic class loading to instantiate a ball given the class name.
  4. New ball instance is added to as an observer to the dispatcher.


What all do we need to create the whole system?





© 2018 by Stephen Wong