Teachpacks for How to Design Classes

# A Functional Drawing Library (HtDC)

###

This `draw` package provides classes and methods for a visual world. Here is its class diagram of public fields and methods:

    import colors.*;
    import geometry.*;

     +-----------------------------------+
     | abstract World                    |
     +-----------------------------------+       +---------------------------------------+
     | Canvas theCanvas                  |------>| Canvas                                |
     +-----------------------------------+       +---------------------------------------+
     | boolean bigBang(int,int,double)   |       +---------------------------------------+
     | boolean endOfTime()               |       | boolean show()                        |
     | World endOfWorld()                |       | boolean close()                       |
     |                                   |       | boolean drawCircle(Posn,int,Color)    |
     |                                   |       | boolean drawDisk(Posn,int,Color)      |
     | abstract World onTick()           |       | boolean drawRect(Posn,int,int,Color)  |
     | abstract World onKeyEvent(String) |       | boolean drawLine(Posn,Posn,Color)     |
     | abstract boolean draw()           |       | boolean drawString(Posn,String)       |
     | abstract boolean erase()          |       | boolean clearCircle(Posn,int,Color)   |
     +-----------------------------------+       | boolean clearDisk(Posn,int,Color)     |
                                                 | boolean clearRect(Posn,int,int,Color) |
                                                 | boolean clearLine(Posn,Posn,Color)    |
                                                 +---------------------------------------+

The abstract `World` class exports the following methods:

- `bigBang(width,height,speed)`, which initializes the world, associates it with a `width` x `height` `Canvas`, displays this canvas, and finally starts the clock at a rate of one tick per `speed` seconds. If it succeeds with all of its actions, the method produces `true`.

  A `World` is associated with one default `Canvas`, called `theCanvas`. If a `World` needs additional canvases for its graphical presentation, its concrete subclasses must add those.

- `endOfTime`, stops the clock and, if it succeeds, produces `true`.
- `endOfWorld`, stops the clock and, if it succeeds, produces the last `World`.

The methods may fail due to the unavailability of the physical devices, inappropriate uses, etc. In those cases, they fail with an exception.

A derived concrete class must supply definitions for the following methods:

- `onTick()`, which is invoked for every tick of the clock. Its purpose is to create a `World` whose differences with `this` one represent what happened during the amount of time it takes the clock to tick.
- `onKeyEvent(key)`, which is invoked for every keyboard event. Its purposes is to create a `World` whose differences with `this` one represent what happens due to the user's use of the keyboard. The latter is represented with the string-valued argument `key`.
- `draw()`, which is invoked after one of the two event handlers has been called. Its purpose is to present `this World` graphically on its canvas. If it succeeds, its result is `true.`
- `erase()`, which is invoked after one of the two event handlers has been called. Its purpose is to erase `this World`'s canvas, as much as needed. If it succeeds, its result is `true.`

A program may, in principle, start several instances of (subclasses of) `World`. If it does, the event handlers are called in a unpredictable order.

To create an instance of the `Canvas` class, a program must supply two `int` values: one for the width of the canvas and one for its height. The canvas is a rectangle, whose borders are parallel to the computer screen's borders. A program can use the following methods on instances of `Canvas:`

- `show()`, which displays the canvas. If it succeeds, it produces `true`.
- `close()`, which destroys the canvas. If it succeeds, it produces `true`.
- `drawCircle(p,r,c)`, which draws a circle on `this Canvas` at `p` with radius `r` and color `c`. If it succeeds, it produces `true`.
- `drawDisk(p,r,c)`, which draws a disk on `this Canvas` at `p` with radius `r` and color `c`. If it succeeds, it produces `true`.
- `drawRect(p,w,h, c)`, which draws a solid rectangle on `this Canvas` at `p` with width `w`, height `h`, and color `c`. The rectangle's lines are parallel to the canvas's borders. If it succeeds, it produces `true`.
- `drawLine(p0,p1,c)`, which draws a line on `this Canvas` from `p0` to `p1` using color `c`. If it succeeds, it produces `true`.
- `drawString(p,s)`, which draws the string `s` at `p` on `this Canvas`. If it succeeds, it produces `true`.
- `clearCircle(p,r,c)`, which erases a circle from `this Canvas` at `p` with radius `r` and color `c`. If it succeeds, it produces `true`.
- `clearDisk(p,r,c)`, which erases a disk from `this Canvas` at `p` with radius `r` and color `c`. If it succeeds, it produces `true`.
- `clearRect(p,w,w,c)`, which draws a solid rectangle from `this Canvas` at `p` with width `w`, height `h`, and color `c`. The rectangle's lines are parallel to the canvas's borders. If it succeeds, it produces `true`.
- `clearLine(Posn p0, Posn p1, Color c)`, which erases a line from `this Canvas` from `p0` to `p1` using color `c`. If it succeeds, it produces `true`.

The methods may fail due to the unavailability of the physical devices, inappropriate uses, etc. In those cases, they fail with an exception.