Homework Assignment 3


  1. Submission Instructions:
    1. A ascii text or pdf file with your answers to questions 1-3 and 5.a-b. It is okay to scan a hand-drawn picture of your class hierarchy in problem 5 and submit a pdf version of the scanned image. Please make sure that the writing in your diagram is easily readable by the TA.
    2. An executable jar file named Queue.jar for question 4.
    3. An executable jar file named Graphics.jar for question 5.

  1. These questions all concern types:

    1. What is a type?
    2. What is a subtype?
    3. What is the relationship between an interface and a type?
    4. What is the relationship between a class and a type?
    5. What is the relationship between a subclass and a type?

  2. Consider the following code: class fruit { public void printType() { System.out.printf("fruit%n"); } public static void main(String args[]) { // code in main to keep it simple fruit f = new orange(); f.printType(); f = new apple(); f.printType(); } }; class orange extends fruit { public void printType() { System.out.printf("orange%n"); } }; class apple extends fruit {};
    1. What is the output of fruit's main method? Explain why you get each of the two output lines.
    2. Suppose that I change the printType declaration for fruit so that it reads:
      final public void printType() { ... }
      
      What happens when you re-compile the three classes? Why does this happen? Do not parrot back the error statement to me. Explain what happens using the virtual/non-virtual method terminology I used in my online lecture on inheritance (the video track entitled "inheritance").

  3. Suppose I am designing a personnel database for a university. The university has three types of personnel: students, staff, and faculty. Here are the characteristics of the three groups:

    1. All three groups have a name and a social security number, both of which are strings, and a gender field, which is a char.
    2. Students have a floating point field for gpa and an integer field for year (e.g., 1 for freshman, 2 for sophomore, etc).
    3. Staff and faculty have a string field for position and a double field for salary.
    4. Staff have an additional integer field for accrued vacation leave.
    5. Faculty have an additional rank field indicating their job title (e.g., professor, associate professor, lecturer)

    Answer the following questions:

    1. Design and draw a class hierarchy for the above objects, based on the given properties. In your class hierarchy place variable names next to each class where you declare them. You will have to create additional superclasses since you will need to factor out some common information.
    2. Which of the above classes should be abstract classes?
    3. Should the getter and setter methods for the properties be declared as virtual or non-virtual? Why?

  4. This problem has several parts that walk you through the creation of an interface and a class that implements the interface:

    1. Create an interface named Queue with the following methods:

      1. void add(Object o): appends an object to the back of the list.
      2. Object remove(): removes and returns an object from the front of the list.
      3. boolean isEmpty(): returns true if the queue is empty and false otherwise.
    2. Create a class called ArrayQueue that implements a queue and that uses an ArrayList from the java.util library to implement the queue.
    3. Create a simple test driver program that:
      1. declares a variable of type Queue,
      2. creates and assigns this variable an object of type ArrayQueue
      3. adds the integers 3, 10, and 5 to the queue (requires an Integer wrapper), removes two elements from the queue and prints them on separate lines, adds the integers 6, 9, and 12 to the queue, and finally empties the queue by calling remove repeatedly until the queue is empty and printing each element. Sample output might be:
        3
        10
        5
        6
        9
        12
        
  5. Using Java write a set of classes that provide the user with a number of graphical objects that they can display on a screen. The objects that you will provide and their properties are:

    1. Rectangle: left, top, width, height, and color
    2. Oval: left, top, width, height, and color
    3. Text: left, top, width, height, color, string
    4. Rounded Rectangle (Roundtangle): left, top, width, height, color, arcsize (int)
    5. Line: x1, y1, x2, y2, color

    A rounded rectangle is a rectangle with rounded corners. The arcsize describes the radius of the circle that rounds the corner. Default values for left and top are 0, for width and height are 20, for color is black, for a string is the empty string, for arcsize is MEDIUM, for x1 and y1 is 0, and for x2 and y2 is 20. All numeric properties are integers, including arcsize. You should define three enumerated constants for arcsize, labeled as SMALL, MEDIUM, and LARGE, but it should be possible for the user to provide any integer as well. The enumerated constant class for arcsize must have the following characteristics:

    1. It must be declared in Roundtangle as public with the name Arcsize.
    2. SMALL should be 10 pixels, MEDIUM should be 20 pixels, and LARGE should be 30 pixels.
    3. It should contain a public method named getSize that returns the number of pixels associated with that constant.
    If you are unsure about how the Arcsize constant is being used, look in GraphicsDriver.java and search for Arcsize. Please note that despite declaring an enumerated set of constants for arcsize, the instance variable that stores the arcsize in a Roundtangle object should be declared as an integer.

    Each object should provide getter and setter methods for its properties (use the getXXXX and setXXXX idiom) and the following methods:

    1. public void draw(Graphics g): Draws this object on the screen. The Graphics class is described below.
    2. public boolean containsPt(int x, int y): Returns true if the object contains and point and false otherwise. For graphical user interfaces it is important to know that the Y-axis starts at the top of the window, not the bottom of the window. Hence if a Rectangle's top is 50, its height is 100 and y is 80, then y lies within the object because the object goes from 50 to 150. For a line, this method should return true if the point lies within a distance of 5 pixels from the line. The easy way to find the distance of a point from a line is to create an instance of Java's Line2D.Double class and call its ptSegDist method. For a rounded rectangle, oval, and text object, it is okay to return true if the point lies within the bounding box of the object. The bounding box is the smallest rectangle that encloses an object, and in this case, the upper left corner of the bounding box is (left, top) and its dimensions are the (width, height) of the object.
    3. public String toString(): Returns a formatted string of the form
      ObjectType(left, top, width, height) or
      Line(x1, y1, x2, y2) or
      Roundtangle(left, top, width, height, ArcSize)
      
      where ObjectType is replaced with the class name, such as Rectangle and ArcSize is replaced with SMALL, MEDIUM, or LARGE..
    4. a zero argument constructor, and
    5. a constructor that takes parameters for each of an object's properties. The one exception is the text constructor, which should only take parameters for its left, top, string, and color properties. You should assume that the height of any string is 16 pixels and that the width of any string is 7 pixels times the length of the string. These are the values I get on my laptop. They may differ somewhat on your laptop but it's too complicated to try to explain at this point in the course how to query java to get the actual width and height of a string (it depends on the number of characters in the string, the font, and the screen's resolution).

    Java provides a couple classes that you will need for this exercise:

    1. Graphics: An instance of this class allows you to draw objects to the screen. If you examine the API for this class, you will see that it has fill commands for rectangles, rounded rectangles (roundtangles), and ovals, and it has draw commands for strings and line. You should use the fill commands for the rectangles, roundtangles, and ovals and the draw commands for the strings and lines. The fill commands fill the body of the object while the draw commands draw the boundary of the object. You will not create an instance of a Graphics class. An instance will be passed by the driver program (see below) to your draw methods.
    2. Color: This class exports a number of predefined colors that you will use for this assignment. Again you will not need to create instances of these colors as the driver program will do so for you. It will pass instances of the Color class to your constructors.

    Look at the Java API to figure out the exact methods you need to use.

    Here are the questions you need to answer for this problem:

    1. Design and draw a class hierarchy for the above objects, based on the given properties. You may need to introduce one or more additional classes over and above the ones associated with the objects described above. My driver program in fact assumes that you have an additional class named GraphicalObject. In your class hierarchy place method names next to each class where you declare them and put an asterisk (*) next to each method that you declare abstract. For example, each of your leaf classes will define a toString method, so the word "toString" should be placed next to each of them. Since each of them provides a method body for the toString method, you would not put an asterisk next to any of them.
    2. Based on your class hierarchy, can the top element in the hierarchy be implemented as an interface, or must it be implemented as a class. Why or why not?
    3. Write the .java files for each of the classes in your class hierarchy. See the driver program I've written to make sure that you create constructors that can be used by the driver program.
    4. Use the driver program, called GraphicsDriver.java, that accompanies this assignment to test your code. If you examine the driver program, you will see that the method pointCheck checks to see whether a point lies in an object and the method paintComponent draws your objects to the screen. However, you may also notice that paintComponent never gets called by main. If you do a little more digging, you will see that GraphicsDriver extends a Java class named JPanel. A JPanel is a "canvas" class that allows objects to be drawn upon it. It has a method named paintComponent that it automatically calls when the canvas should be redrawn. I have overridden the paintComponent method in order to draw your objects. The window knows that the GraphicsDriver jpanel is attached to it because of the following command towards the end of main:
      window.getContentPane().add(this, BorderLayout.CENTER);
      
      Remember that this is a pointer to the current object, which in this case is the GraphicsDriver jpanel. We will talk more about Java's graphics later in the course.

Input

The graphics driver reads its input from stdin. The input consists of a series of object creation commands, followed by a single line with the word end, followed by a series of lines with (x, y) integer points. Each object should be input on a separate line, and should start with one of the keywords rectangle, oval, roundtangle, text, or line. It should then be followed by properties in the order shown above. For arcsize, the user may enter SMALL, MEDIUM, LARGE, or an integer value. Colors should be entered as strings in all lowercase. For example, black is entered as the string "black". For text objects, you will only enter the left, top, color, and string properties. The string should be treated as all words after the color. Hence if the line reads:

text 20 40 green Brad Vander Zanden
then you should create a text object whose coordinates are (20,40) and whose string is rendered in green as "Brad Vander Zanden."

A sample input file named input accompanies this assignment and looks as follows:

rectangle 10 10 50 60 red
oval 70 80 100 20 blue
line 10 30 80 90 magenta
text 30 40 green Brad Vander Zanden
roundtangle 200 200 80 80 black LARGE
rectangle 300 300 100 100 gray
text 210 210 yellow Nels
oval 0 300 50 100 orange
roundtangle 500 100 80 30 red 15
end
30 30
100 90
10 200
240 240
520 120
A sample execution of your program might be:
java -jar Graphics.jar < inputFile
where inputFile is the name of your input file.

Note to OS X Mavericks users: Your program will work, but some of you with older versions of the OS may see an error message that reads something like:

Jan 27 11:46:51 lap6.local java[29672] : The function `CGContextErase' is obsolete
and will be removed in an upcoming update. Unfortunately, this application, or a library it 
uses, is using this obsolete function, and is thereby contributing to an overall degradation of 
system performance.
Ignore this message.

Hints

  1. If you have a question about how your output should look, try running /home/bvanderz/courses/365/sp21/hw/hw3/Graphics.jar. We will be using script grading so your output must match my output. It is much easier to try to download my .jar file and run it locally on your machine than it is to try to run it on the hydra machines. The same goes for executing your own java executable. The reason is that if you try to execute the .jar files on the hydra machines, then you will get an error message about no X11 Display variable being set (the hydra machines are running the X11 window system and your computer most likely is not). This error can be overcome with X11 forwarding, but you have to enable such forwarding when you ssh into the hydra machines. You can attempt to enable X11 forwarding with the flags -X and -Y as follows:
    ssh -X -Y username@hydra1.eecs.utk.edu
    
    Based on my experience from Spring 2017, this works well with linux and windows boxes, and will work on a Mac if you install/update XQuartz.

  2. You will need to import from the following two libraries in order to access the appropriate graphics classes:
    1. java.awt
    2. java.awt.geom