Put all work into a directory hw6
of your Git project and push it once a day. Don't put any code into packages. Don't put any code into a src
subdirectory.
You will put the DECORATOR and COMPOSITE patterns to work, by decorating and composing icons and shapes.
Implement a class BoxedIcon
that implements the Icon
interface and that puts a box around an Icon
, like this:
In the constructor, provide the decorated icon and the padding, i.e. the number of blank pixels between the rectangle (which is 1 pixel thick) and the decorated icon. Be sure to count the pixels exactly. If the padding is zero, there should be no space between the decorated icon and the rectangle.
Here is code to test these classes:
That's the easy part. Now we want to do the same with the java.awt.Shape
interface. That is, a BoxedShape
is a decorator for a Shape
that adds a box around it, and a CompositeShape
is a collection of shapes that is itself a Shape
. Here is such a composite shape:
That's tricky because the Shape
interface is complex. There are methods to test for containment, bounds, and intersection. The variations of these methods are somewhat repetitive because there were no default methods when this interface was created, and nobody bothered adding them later.
The actual shape is described by a PathIterator
, so we get to practice the ITERATOR pattern too. A shape iterates over issuing commands “move to”, “line to”, “quad to”, “cubic to”, and “close”. Think of “quad to” and “cubic to” as describing curved lines. These commands are sufficient to make any kinds of complex shapes. For example, in all digital fonts, letters are actually rendered as sequences of linear, quadratic, and cubic curve segments.
I don't want you to fret over those details, so I give you a BoxedShapePathIterator
that first issues the commands to draw a box, then the commands that the decorated shape iterator provides.
Similarly, the CompositeShape
returns a CompositeShapePathIterator
. Each individual shape has an iterator. Make it so that the first one gets to report its moves and curves, then the next one does the same, and the next one. You don't need to know what any of them does.
I give you the CompositeShape
. Most of its methods are routine; for example, the bounds are the union of the bounds of the components.
Here is code to test these classes:
These are the classes you must submit.
BoxedIcon.java
BoxedShape.java
CompositeIcon.java
CompositeShapePathIterator.java
You may submit any additional classes that you need, or that I provided.
As always, add Javadoc comments, and don't use tabs. There will be CheckStyle!
PS. Don't copy/paste these files. Either right-click and select Save As, or even better, use:
curl -O http://horstmann.com/sjsu/spring2019/cs151/hw6/IconTester.java curl -O http://horstmann.com/sjsu/spring2019/cs151/hw6/ShapeIcon.java ...
PPS. Remember to first fetch these files and put them into a directory hw6
inside your Git repo, then make your Eclipse project by browsing that hw6
directory.