Skip to content

Homework 7: Wonder Wall

Learning Objectives

After completing this homework, you should be able to:

  • Implement a UML diagram that uses inheritance without code duplication.
  • Implement examples of overloading and overriding methods.
  • Use polymorphism to simplify code using an inheritance hierarchy.
  • Use a medium-sized library to develop new code by reading documentation.

This assignment must be completed individually. Your work must comply with the JMU Honor Code. Authorized help is limited to general discussion on Piazza, the lab assistants assigned to CS 159, and the instructor. Copying code from someone else, including the use of generative AI, is prohibited and will be grounds for a reduced or failing grade in the course.

Introduction

This assignment uses inheritance and demonstrates the concept of polymorphism enabling more efficient code development and maintenance. You will be using the StdDraw library to create a "Wonder Wall" of pictures. Inspired by the world of pictures in Harry Potter, some of the pictures on this wall will move as if in a slide show.

Th Wonder Wall can have three types of pictures. The parent class, Picture, can be used to create still framed pictures. TitledPicture can be used to create pictures labeled with a unique number and title. SlideShow can be used to create a picture that has a rotating set of images within the frame.

Gallery.java demonstrates how all these classes, along with Wall, can be used to create a gallery of different styles of pictures, as if they were hanging on a wall. Used with the provided images and properly written code, the pop-up display should look like the image below when Gallery.java is executed. The picture on the left will cycle through four seasonal pictures.

WonderWall

Notes about using StdDraw

For this homework, we will make use of StdDraw.java ("Standard Draw") developed by Robert Sedgewick and Kevin Wayne at Princeton University. This class provides a set of methods for creating simple drawings. You can find the complete documentation online and instructions for downloading the .jar file below.

Note that the StdDraw library significantly simplifies the work of using the java graphics library. The "canvas" indicates the visible part of the pop-up StdDraw window. The difficult part of using the canvas and positioning pictures is handled by the parent (super) class in Picture.java and the example application Gallery.java.

By default, StdDraw considers the canvas to be a unit square where:

  • The location (0, 0) is in the lower-left corner of the StdDraw window.
  • The location (1, 1) is in the upper-right corner of the StdDraw window.

This homework, however, considers the canvas to be a 1024 wide by 512 high rectangle:

  • The location (0, 0) is in the lower-left corner of the window.
  • The location (1024, 512) is in the upper-right corner of the window.

This change in the size of the canvas enables code to use integer values as position locations. The scaling factor of 512 enables calculations for locations to also be appropriate for this new coordinate system. Note that increasing in the x (horizontal) direction moves right on the canvas and increasing in the y (vertical) direction moves up on the canvas.

Also, note that the default pen color is black and the default canvas color is white. You will not need to change the background canvas color in this project, but you will need to change the default pen color and radius.

UML Diagram

The provided classes are outlined in red. Be sure not to edit those classes (especially Picture).

classDiagram

class Gallery {
    +WALL_SCALE: int = 512$

    +main(args: String[])$
}

class Frame {
    +JMU_PURPLE: Color = (69, 0, 132)$
    +JMU_GOLD: Color = (203, 182, 119)$
    +INNER_RADIUS: double = 0.01$
    +OUTER_RADIUS: double = 0.02$
    -outerColor: Color
    -innerColor: Color

    +Frame()
    +Frame(innerColor: Color, outerColor: Color)
    +getOuterColor() Color
    +setOuterColor(outerColor: Color)
    +getInnerColor() Color
    +setInnerColor(innerColor: Color)
    +equals(other: Object) boolean
    +toString() String
}

note for Frame "Frame imports java.awt.Color from the Java library.
The (red, green, blue) values for JMU_PURPLE and
JMU_GOLD are arguments for the Color constructor."

class Picture {
    -picCount: int$
    -x: int
    -y: int
    -width: int
    -height: int
    -scale: double
    -filename: String
    -frame: Frame
    -fwidth: double
    -picNum: int

    +Picture(x: int, y: int, width: int, height: int,  \n         scale: double, filename: String)
    +getX() int
    +getY() int
    +getWidth() int
    +getHeight() int
    +getScale() int
    +getFilename() String
    +setFilename(filename: String)
    +getFrame() Frame
    +getFwidth() double
    +getPicNum() int
    +equals(other: Object) boolean
    +draw()
    +toString() String
}

class SlideShow {
    +SLIDE_SHOW_PAUSE: int = 2000$
    -picFiles: ArrayList~String~
    -currentPic: int

    +SlideShow(x: int, y: int, width: int, height: int, \n         scale: double, picFiles: ArrayList~String~)
    +getCurrentPic() int
    +equals(other: Object) boolean
    +draw()
    +toString() String
}

class TitledPicture {
    +TEXT_HEIGHT: int = 12$
    +CHAR_WIDTH: int = 4$
    +PIC_NUM_CHARS: int = 4$
    -title: String

    +TitledPicture(x: int, y: int, width: int, height: int, \n         scale: double, filename: String, title: String)
    +draw()
    +toString() String
}

class Wall {
    +WALL_WIDTH: int = 1024$
    +WALL_HEIGHT: int = 512$
    -pics: ArrayList~Picture~

    +Wall(pics: ArrayList~Picture~)
    +getPics() ArrayList~Picture~
    +display()
}

Gallery --> Wall
Wall --> Picture
Frame <-- Picture
Picture <|-- SlideShow
Picture <|-- TitledPicture

style Gallery stroke:#f00,line:#f00,fill:#aaaaaa22
style Picture stroke:#f00,line:#f00,fill:#aaaaaa22

Download Provided Files

Download and unzip the provided code (and move into your src/hws/ folder):

Do not change the code in Picture.java or your code will not work correctly on Gradescope.

If you have not already done so, download and move the following JAR file into your lib folder:

Create Frame.java

Frame.java should be implemented as shown in the above UML. First declare the four given constants and the two attributes.

Constructors

The default constructor should initialize a Frame with an inner color of JMU_GOLD and an outer color of JMU_PURPLE. The other constructor should initialize the inner and outer colors from the given parameters of the same name.

Getters and setters

Getters and setters for innerColor and outerColor should simply return or assign the attribute as specified in the name of the method.

equals

The equals method should make sure the object is of the correct type and then verify that the inner color and outer color are equal for this object and the parameter obj.

toString

The toString method should start with the word "Frame" followed by a space and a [, then outercolor= followed immediately by the toString for outerColor, then a comma, a space, and then innercolor= followed immediately by the toString for innerColor.

For example, if outerColor is JMU_PURPLE and innerColor is JMU_GOLD then the String returned should be:

Frame [outerColor=java.awt.Color[r=69,g=0,b=132], innerColor=java.awt.Color[r=203,g=182,b=119]]

Create SlideShow.java

SlideShow.java represents a picture frame that has a revolving set of pictures displayed. The class should have the constant and attributes as shown in the UML diagram above. As indicated by the triangle arrow, SlideShow should extend Picture to prevent code duplication.

Constructor

The single constructor for SlideShow should use the constructor for Picture with an initial picture filename of the first filename in the parameter picFiles. It should then initialize the current picture (index) to 0, and copy each of the strings in the parameter picFiles to the attribute picFiles.

getCurrentPic

There should just be one getter in SlideShow. getCurrentPic should just return currentPic.

equals

The equals method should override the equals method in Picture and return true if and only if the filenames in picFiles are exactly the same and in the same order in the compared objects. Hint: Use the ArrayList.equals method.

draw

This method should draw the picture exactly as done in Picture. Then it should advance the currentPic by one (or wrap around to 0 if already on last picture) and set the picture filename to the name from the attribute picFiles as indicated by the new currentPic.

toString

toString should return a string that consists of the exact string created by Picture toString, and then each of the filenames in picFiles preceded by a newline. This will create a string where each filename is on it's own line, but there is no newline at the end of the string. For example:

Picture: 1 hws/hw7/img/Spring.jpg at 200, 256 size: 200 by 150
Frame [outerColor=java.awt.Color[r=69,g=0,b=132], innerColor=java.awt.Color[r=203,g=182,b=119]]
hws/hw7/img/Spring.jpg
hws/hw7/img/Summer.jpg
hws/hw7/img/Fall.jpg
hws/hw7/img/Winter.jpg

Create TitledPicture.java

TitledPicture.java represents a picture that includes a unique number and title on the bottom of the picture. The class should have the constants and attribute as shown in the UML diagram. As indicated it should also extend Picture.java to prevent code duplication.

Constructor

The single constructor for TitledPicture should use the constructor for Picture and initialize the title attribute.

draw

draw should draw the picture exactly as done in Picture.

Add a white rectangle in the middle of the bottom of the picture at a height just above the frame. Specifically, the x position of the rectangle should be at the same place as the picture. The y position should be the frame width above the bottom of the picture. The bottom of the picture can be computed from the vertical center of the picture (its y position) and subtracting half of the height of the picture. You would need to compute that and then add the frame width.

The "half" width of the rectangle should be the length of the title plus the number of characters for the picture number as indicated in the constant, PIC_NUM_CHARS, multiplied by the character width, CHAR_WIDTH. The "half" height of the rectangle should be the constant, TEXT_HEIGHT. Note that the method to draw a rectangle in StdDraw uses "half" width and height so the values described are the arguments you need to use to call the method.

Add black text to include the unique identifier of the picture object along with the title. To form the text to be printed, use picNumfollowed by a colon and a space, and then the title attribute. The x and y position of the text should be the same as the x and y position of the white background rectangle.

Hints

  1. Make sure to change the pen color to make the white rectangle and then again to write the text.
  2. Use the filledRectangle method in StdDraw.

toString

toString should return a string that consists of the exact string created by Picture toString, followed by a newline, and then the word "Title: ", followed by the title. There is no newline at the end of the string. For example:

Picture: 2 hws/hw7/img/Weikle.jpg at 800, 256 size: 75 by 75
Frame [outerColor=java.awt.Color[r=69,g=0,b=132], innerColor=java.awt.Color[r=203,g=182,b=119]]
Title: Weikle

Create Wall.java

Wall.java represents a two-dimensional wall of pictures and a method of displaying those pictures by invoking each picture's draw method. The class should have the constants and attribute as specified in the UML diagram.

Constructor

The constructor should create a new ArrayList and copy the Picture references from the pics parameter. This is a shallow copy — you do not need to make a copy of each Picture object. Hint: Use the copy constructor in ArrayList.

getPics

The single getter in Wall should return the attribute.

display

display should call the draw method on each picture in the attribute pics, regardless what type of Picture objects are stored.

Submission

You will submit only four files:

  • Frame.java
  • SlideShow.java
  • TitledPicture.java
  • Wall.java

Note: Picture.java and Gallery.java are provided for you and should not be submitted for either part.

The submission will be broken into two parts: Part A and Part B. Submit the same four files to each part.

Part A: Stubs

Part A should include appropriate Javadoc comments and stubs, passing both compiler tests and Checkstyle. You have unlimited submissions for Part A.

Part B: Completed Files

You have 10 submissions for Part B. To receive full credit, your SlideShow, TitledPicture and Wall must correctly make use of the inheritance hierarchy to prevent code duplication. Use polymorphism whenever possible, especially in Wall.

Grading Criteria

Your code will first be graded by Gradescope and then by the professor. The grade you receive from Gradescope is the maximum grade that you can receive on the assignment.

Note that Gradescope cannot determine if your draw methods work correctly. You should be testing your methods as you work. Run Gallery.java on your completed files.

After the due date, the professor may manually review your code. At that time, points may be deducted for inelegant code, inappropriate variable names, bad comments, etc. Specific care should be taken on this assignment to not duplicate code provided in Picture.java.

Your code must compile with the official tests and pass a Checkstyle audit for you to receive any points. For full credit, your code must make proper use of the inheritance hierarchy.

Gradescope will provide you with hints but might not completely identify the defects in your submission. You are expected to test your own code before submitting.

Part A: Stubs

Criterion Points Details
Compile 5 pts Success Required
CompileOfficialTests 5 pts Partial Credit Possible
Style 10 pts Partial Credit Possible

Part B: Completed Files

Criterion Points Details
Compile 0 pts Success Required
CompileOfficialTests 0 pts Success Required
Style 0 pts Success Required
OfficialTests 80 pts Partial Credit Possible