Computer Science 120
Introduction to Programming

Spring 2011, Siena College

DragAllRoads Demo

A working demo of DragAllRoads will appear below. Click inside the applet to interact with it.



DragAllRoads BlueJ Project

Click here to download a BlueJ project for DragAllRoads.


DragAllRoads Source Code

The Java source code for DragAllRoads is below. Click on a file name to download it.


DragAllRoads.java

import objectdraw.*;
import java.awt.*;

/* $Id: DragAllRoads.java 1577 2011-03-28 02:10:20Z terescoj $ */

/**
 * Example DragAllRoads: draw "road segments" at mouse
 * press points, but drag any existing segment instead
 * if it happens to contain the mouse press point.
 *
 * @author Jim Teresco
 * Siena College, CSIS 120, Spring 2011
 *
 */

public class DragAllRoads extends WindowController {
    
    // the road segments in our drawing
    private static final int INITIAL_ARRAY_SIZE = 4;
    private RoadSegment[] segments;
    private int numSegments;
    
    // the road segment currently being dragged, if any
    private RoadSegment selectedSegment;
    
    // last mouse point and boolean flag to support dragging
    private boolean dragging;
    private Location lastMouse;
    
    /**
     * Set up: just initialize the array of segments
     * and set other instance variables.
     */
    public void begin() {
    
        segments = new RoadSegment[INITIAL_ARRAY_SIZE];
        numSegments = 0;
        selectedSegment = null;
        dragging = false;
        lastMouse = null;
    }
    
    /** Draw a road segment at the mouse press point
     *  unless the most recent road drawn was at that
     *  point, in which case we begin a drag operation.
     * 
     *  @param point the Location of the mouse press
     */
    public void onMousePress(Location point) {
    
        // see if we've pressed the mouse on an existing road segment
        for (int segmentNum = 0; segmentNum < numSegments; segmentNum++) {
            
            if (segments[segmentNum].contains(point)) {
                selectedSegment = segments[segmentNum];
                dragging = true;
                lastMouse = point;
            }
        }
        
        // if dragging is still false, we create a new segment
        if (!dragging) {
            
            // need to check first if there is still room in our array
            // and if not, build a new one with more room.
            if (numSegments == segments.length) {
                // create a new array with twice as many slots
                RoadSegment[] newArray = new RoadSegment[segments.length*2];
                // copy over the entries from the old array to the new
                for (int segmentNum = 0; segmentNum < segments.length; segmentNum++) {
                    newArray[segmentNum] = segments[segmentNum];
                }
                // replace the old array with the new, larger one
                segments = newArray;
            }
            // create the new segment and insert it into the first
            // empty slot (which we now are sure exists).
            segments[numSegments] = new RoadSegment(point, canvas);
            numSegments++;
            dragging = false;
        }
    }
    
    /** Perform dragging operation if we are dragging anything
     * 
     *  @param point the Location of the mouse press
     */
    public void onMouseDrag(Location point) {
     
        if (dragging) {
            selectedSegment.move(point.getX() - lastMouse.getX(),
                                 point.getY() - lastMouse.getY());
            lastMouse = point;
        }
    }
    
    /** Complete dragging operation if we are dragging anything
     * 
     *  @param point the Location of the mouse press
     */
    public void onMouseRelease(Location point) {
     
        if (dragging) {
            selectedSegment.move(point.getX() - lastMouse.getX(),
                                 point.getY() - lastMouse.getY());
            dragging = false;      
        }
    }  
 }

RoadSegment.java

import objectdraw.*;
import java.awt.*;

/* $Id: RoadSegment.java 1577 2011-03-28 02:10:20Z terescoj $ */

/**
 * Class to draw a simple road segment at a given point
 * on the given canvas, with contains and move capabilities.
 * 
 * @author Jim Teresco
 * Siena College, CSIS 120, Spring 2011
 */

public class RoadSegment {
 
    // constant parameters defining the sizes for the road segment
    private static final int ROAD_WIDTH = 50;
    private static final int ROAD_LENGTH = 200;
    private static final int STRIPE_WIDTH = 3;
    private static final int STRIPE_LENGTH = 20;
    private static final int STRIPE_SPACING = 20;
    private static final int SIDE_STRIPE_INSET = 2;
    
    // default colors
    private static final Color ROAD_COLOR = new Color(32, 32, 32);
    private static final Color SIDE_LINE_COLOR = Color.white;
    private static final Color CENTER_LINE_COLOR = Color.yellow;
    
    // the graphical components of our road segment
    private FilledRect pavement;
    private FilledRect sideStripe1, sideStripe2;
    private FilledRect[] centerStripes;
    
    /**
     * Construct a new RoadSegment
     * 
     * @param point the Location of the upper left corner of the segment
     * @param canvas the DrawingCanvas on which to draw
     */
    public RoadSegment(Location point, DrawingCanvas canvas) {
        
        // the pavement
        pavement = new FilledRect(point, ROAD_WIDTH, ROAD_LENGTH, canvas);
        pavement.setColor(ROAD_COLOR);
        
        // side stripes
        sideStripe1 = new FilledRect(point.getX() + SIDE_STRIPE_INSET, point.getY(),
                                     STRIPE_WIDTH, ROAD_LENGTH, canvas);
        sideStripe1.setColor(SIDE_LINE_COLOR);
        sideStripe2 = new FilledRect(point.getX() + ROAD_WIDTH - SIDE_STRIPE_INSET - STRIPE_WIDTH,
                       point.getY(), STRIPE_WIDTH, ROAD_LENGTH, canvas);
        sideStripe2.setColor(SIDE_LINE_COLOR);
                      
        // center stripes, draw from bottom to top
        double nextStripeY = point.getY() + ROAD_LENGTH - STRIPE_LENGTH;
        double stripeX = point.getX() + ROAD_WIDTH/2 - STRIPE_WIDTH/2;
        
        // construct an array large enough to hold our stripes
        int numStripes = ROAD_LENGTH/(STRIPE_LENGTH + STRIPE_SPACING);
        centerStripes = new FilledRect[numStripes];
        
        for (int stripeNum = 0; stripeNum < numStripes; stripeNum++) {

            centerStripes[stripeNum] = 
               new FilledRect(stripeX, nextStripeY, STRIPE_WIDTH, STRIPE_LENGTH, canvas);
            centerStripes[stripeNum].setColor(CENTER_LINE_COLOR);
            nextStripeY = nextStripeY - STRIPE_LENGTH - STRIPE_SPACING;
        }
    }
    
    /**
     * Return if the given location is within the graphical area covered by this
     * road segment
     * 
     * @param point the Location to check for containment
     * @return whether the given Location is in this road segment
     */
    public boolean contains(Location point) {
          
        return pavement.contains(point);
    }
    
    /**
     * Move the road segment by the given x and y offsets.
     * 
     * @param dx the amount to move in the x coordinate
     * @param dy the amount to move in the y coordinate
     * 
     */
    public void move(double dx, double dy) {
        
        // move each component by these offsets
        pavement.move(dx, dy);
        sideStripe1.move(dx, dy);
        sideStripe2.move(dx, dy);
        for (int stripeNum = 0; stripeNum < centerStripes.length; stripeNum++) {
            centerStripes[stripeNum].move(dx, dy);
        }
    }
}