CSC 212: Programming with Data Structures

Homework 2: Viewing Maps

Due: Wednesday, Feb. 10, 11:59pm

Credit for this assignment: Nick Howe


Class Specifics: MapViewer

The MapViewer class will be responsible for displaying a particular view of a particular MapGrid. Thus it must have a field to keep track of the MapGrid to be displayed, and additional fields holding the parameters describing how the map will be drawn within the viewpoint. These will consist of a magnification or scale specifying the size (in pixels) of the square that should be drawn for each grid element, and an offset specifying where the upper left corner of the map grid squares should be drawn relative to the viewport window. The offset could be stored as two int fields, or the more ambitious can store it using the core Java class Point.

Once the fields are defined, you should turn to the constructors, accessors, and manipulators. The constructor need only take a MapGrid as an argument, and set reasonable values for the viewpoint fields (for example, origin at (0,0) and magnification 10). If you wish, you may define a second constructor with arguments that set all the fields to arbitrary values, and/or a copy constructor. There should also be standard accessors and manipulators for all fields (except perhaps the MapGrid itself).

Because the MapViewer class needs to display things in a graphics window, it must be a subclass of Java's JComponent class. For proper behavior, it will need to override three methods inherited from the parent class. First of all, paintComponent() should be modified so that it displays the current view of the map, as described in further detail below. Also, the getMinimumSize() and getPreferredSize() should both return the size of the displayed area in pixels; this should be returned in the form of a Java Dimension class. The values to return may be computed from the dimensions of the visible area and the magnification.

(One other note: Just as there are methods you must override when you inherit from an existing class, there are others you should be careful not to. JComponent already has methods named getX(), getY(), getHeight(), and getWidth(). If you accidentally override any of these with your own versions, you will probably get very interesting and hard-to-understand bugs!)

The easiest way to draw the map is to simply simply to draw every square of the grid, starting from the offset position. (For example, if the magnification is 10 and the offset is (0,0), then the upper left square of the map will extend from (0,0) to (10,10). But if the offset is (-15,25) then the square should be drawn from (-15,25) to (-5,35) instead. The square immediately to its right will extend from (-5,25) to (5,35), etc.)

To carry out the drawing you will make two nested loops, one over the rows and the other over columns, and inside the inner loop you will draw one rectangle of the appropriate color, and compute its coordinates from the loop indices, the offsets, and the magnification. Areas that do not fall within the coordinates of the viewing window will not be visible, but it doesn't hurt to attempt to draw them. (Note that this is not necessarily the most efficient approach, but we are making it easy on ourselves.) Conversely, your program should still be able to operate if the offset is such that an area beyond the map's edge will appear in the window. You can leave this undefined area in some uniform color.

The diagrams below illustrate the behavior of the viewer. The map coordinates are shown because paintComponent() will need them to draw the squares correctly.

This shows the situation with an offset of (0,0) and a magnification of 6. The red dashed line shows the outline of a 42x36 pixel viewing area. Coordinates are shown at the corner point of each map square, for selected squares. The square boundaries are shown here for clarity; the actual viewer window will display something like the image below:


This shows the situation with an offset of (0,0) and a magnification of 4. The viewing area is the same as before. Only the portion below will be visible in the viewer window.


This shows the situation with an offset of (-15,-6) and a magnification of 6. The red dashed line shows the outline of the viewing area, and the purple arrow shows the offset of the map origin relative to the viewport origin. Compare the coordinates in the first example with the one here: the offset is added to the coordinates of all the squares. Only the portion below will be visible in the viewer window.


This shows the situation with an offset of (12,-32) and a magnification of 6. In this case, part of the viewer window has no map data. You may show undefined areas in white, black gray, or any other color you wish, but your viewer will ideally handle situations like this without any trouble. The viewer window display for this situation is shown below.