Homework 5


This homework is designed to give you some practice with object modeling and with animation. For this assignment you are going to write 4 classes and then write a simple GUI that uses them. The 4 classes you will write are as follows (you do not have to literally declare each property as an instance variable--you could for example declare a Rectangle object that stores the position and size properties and then implement methods that return these values individually):

  1. RectShape: This class should have the following properties and methods:

    1. Properties
      1. int left, top: The upper, left corner of the rectangle
      2. int width, height: The size of the rectangle
      3. Color fillColor: The fill color of the rectangle
      4. Color lineColor: The boundary color of the rectangle
      5. boolean filled: True if the rectangle should be filled and false otherwise
      6. boolean border: True if the rectangle should have a border and false otherwise
    2. Methods
      1. void draw(Graphics2D g): Draws the rectangle
      2. boolean contains(int x, int y): true if the rectangle contains the point and false otherwise
      3. Get/Set methods for the properties

  2. TextShape
    1. Properties
      1. int left, top: The upper left corner of the text. In order to draw the text, you will have to add the font's ascent to the top so that you draw at the proper baseline.
      2. int width, height: These properties should be read-only and should be calculated from the text shape's string and font.
      3. String label: The text shape's string
      4. Font font: The text shape's font.
      5. Color fillColor: The fill color of the text shape
      6. Color lineColor: The color of the text shape's string
      7. boolean filled: True if the text shape should be filled and false otherwise
    2. Methods
      1. void draw(Graphics2D g): Draws the text shape.
      2. boolean contains(int x, int y): true if the text shape contains the point and false otherwise
      3. Get/Set methods for the properties

  3. CanvasShape
    1. Properties
      1. int width, height: the desired width and height of the CanvasShape.
      2. Vector shapes: a list of the shapes the canvas is supposed to draw. This vector should store AbstractShapes, where AbstractShape is the superclass for all shapes.
      3. TotalRedraw displayMgr: a pointer to the display manager which handles the drawing of this canvas.
    2. Methods
      1. Dimension getPreferredSize(): returns the desired width and height of the CanvasShape (this is how you should "set" the width and height)
      2. set/get methods for the properties (but not setWidth or setHeight, since these are "set" via the getPreferredSize method).
      3. void add(AbstractShape): Adds a shape to the canvas
      4. void paintComponent(Graphics g): calls the display manager in order to draw the canvas

  4. TotalRedraw: A display manager that completely redraws the canvas. You can use the algorithm shown in class. TotalRedraw does not need to either extend any class nor implement any interface.
    1. Properties
      1. CanvasShape: The canvas that the display manager is drawing
    2. Methods (damage method is not necessary)
      1. void display(Graphics2D g): draws the canvas
      2. get/set methods for setting the properties


Graphical Interface to Create

You are going to create a graphical interface that displays a set of colored labeled boxes. Your interface should have the following properties:

  1. You will create the interface by creating a JFrame and adding your CanvasShape to the JFrame. You may use a BorderLayout and add your CanvasShape to the center region.
  2. The canvas should be 600x500 pixels.
  3. The labeled boxes should be rectangles with text shapes inscribed in them. The text shapes should be centered both vertically and horizontally in the rectangle. The rectangle should be 20 pixels wider, and 20 pixels higher than its inscribed text shape.
  4. The leftmost region (i.e., the West region of the window) should have a set of widgets for creating a new labeled box:

    1. There will be a button that displays a JColorChooser object. The user will select the fill color for the rectangle. Next to the command button should be a rectangular chip that displays the selected color. It should be one of your rectangle shapes and it should be added to one of your canvas shapes. Since the canvas shape is a JPanel, you can add it to your region in the normal way and use an appropriate layout manager to layout the color choose button and the rectangular chip side-by-side.
    2. There will be text boxes to specify the left and top of the labeled box.
    3. There will be a text box for entering the label
    4. There will be a command button for creating a new labeled rectangle using the information gathered from your other widgets.

  5. The topmost region (i.e., the North region of the window) should be divided into a leftmost region that has a set of widgets for animatedly moving the selected labeled box around the screen and a rightmost region for setting the font of the selected labeled box.

    1. Animation Controls

      1. There will be text boxes for specifying the destination left and top locations of the labeled box.
      2. There will be a slider for specifying the number of seconds that the animation should take. The animation should take from 1-10 seconds. Your animation may take a bit longer because Swing timers will drift.
      3. There will be a command button for invoking the animation.
      4. The animation controls should be disabled if no labeled box is selected, to prevent the user from making an error.

    2. Font Controls

      1. There should be radio buttons for specifying the font size as small, medium, or large. The font sizes corresponding to these sizes should be 8, 12, and 24.
      2. The font controls should be disabled if no labeled box is selected, to prevent the user from making an error.
      3. When a labeled box is selected, the radio button corresponding to the box's font size should be selected. When no box is selected, it is ok to let the last selected radio button remain selected.

    3. A labeled box may be selected by clicking on it with the mouse. If another labeled box was previously selected, it should become de-selected. If the mouse is clicked over an empty region of the canvas, then any previously selected labeled box should be de-selected. Selected labeled boxes should be given a blue border, become unfilled, and render their text in white (the text background should still be black). For this assignment you should attach a mouse listener to the Canvas Shape and iterate through the canvas's shapes, querying each one in turn, to determine whether or not they contain the mouse point. If they contain the mouse point, then you should select them.

    4. The following properties of a labeled box should be static:

      1. The text should be rendered in yellow, unless its labeled box is selected, in which case it should be rendered in white.
      2. The text should be a sans-serif font with a plain style. The default font size will be medium (12) but can be changed by the font controls.
      3. The text background should be black
      4. A labeled box's border should be black, unless it is selected, in which case it should be blue.


Hints

  1. Use JLabel's to label your widgets.

  2. Use a common superclass for RectShape and TextShape, called AbstractShape, even though TextShape does not have a border property. The draw method for a TextShape will simply ignore the border property. If you use a common superclass, you can share the implementation for many of the two class's methods.

  3. Make your labeled box be a class that extends the AbstractShape class. The draw method can call the draw methods for the rectangle shape and the text shape and the contains method can call the rectangle's contains method.

  4. You may find that using an IDE, such as NetBeans or Eclipse, makes the creation of the control windows much faster. The layout of your control windows does not have to exactly mimic the layout of my control windows. However, if you use an IDE, you may find it impossible to resize your window. That is okay. You will note that I used an IDE and that my window cannot be re-sized without messing up the control windows.

  5. You can use the command:
    Toolkit.getDefaultToolkit().getFontMetrics(Font f)
      
    to get a FontMetrics object to measure the width and height of a string that is rendered in a Font f. You will be able to use this FontMetrics object before a TextShape is attached to a window (i.e., added to a CanvasShape, which is in turn added to a JFrame). In general this is poor technique because you should only try to position objects at rendering time, which in Java speak means when paintComponent gets called. You will get a warning about using a deprecated method--that is okay. I am allowing you to use this command for this assignment because you already have a significant task in trying to understand how to do object modeling, and having you defer positioning until rendering time would add unneeded complexity to the assignment.


What to Submit

Submit a jar file named LabeledBox.jar with the following files:

  1. A set of appropriately named .java files (one for each of your classes).
  2. A file named LabeledBoxApplication.java that contains the code for setting up your interface.
  3. A manifest.txt file that indicates that LabeledBoxApplication is your main class.
  4. All your class files.

We will expect to be able to execute your jar file by typing:

java -jar LabeledBox.jar