Computer Science 252
Problem Solving with Java

Spring 2014, The College of Saint Rose

SimpleRecScribbler Demo

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



SimpleRecScribbler BlueJ Project

Click here to download a BlueJ project for SimpleRecScribbler.


SimpleRecScribbler Source Code

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


SimpleRecScribbler.java

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import objectdraw.*;

/*
 * This program is another step toward a drawing program that will 
 * be much more functional than our simple Scribble example.
 * Here, we construct a recursive data structure to represent
 * a Scribble, and can move and change the color of the
 * Scribbles.
 *
 * Jim Teresco, CSC 252, The College of Saint Rose, Fall 2013
 * Based on similar example from Williams College CS 134.
 * 
 * $Id: SimpleRecScribbler.java 2230 2013-10-27 02:26:10Z terescoj $
 */

// A very simple drawing program.
public class SimpleRecScribbler extends WindowController
    implements ActionListener {

    // user modes
    // using ints rather than boolean to allow for extension to
    // other modes
    private static final int DRAWING = 1;
    private static final int MOVING = 2;

    // the current scribble
    private Scribble currentScribble;

    // stores last point for drawing or dragging
    private Location lastPoint;

    // whether the most recent scribble has been selected for moving
    private boolean draggingScribble;

    // buttons that allow user to select modes
    private JButton setDraw, setMove;

    // the current mode -- drawing by default
    private int chosenAction = DRAWING;

    public void begin() {
        // create the user interface components
        Container contentPane = getContentPane();
        setDraw = new JButton("Draw");
        setMove = new JButton("Move");

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(setDraw);
        buttonPanel.add(setMove);

        contentPane.add(buttonPanel, BorderLayout.SOUTH);

        // add listeners
        setDraw.addActionListener(this);
        setMove.addActionListener(this);

        contentPane.validate();
        
        // make the current scribble empty
        currentScribble = new Scribble(null, null);
    }


    public void onMousePress(Location point) {
        if (chosenAction == DRAWING) {
            // start a new (empty) scribble for drawing
            currentScribble = new Scribble(null, null);
        } else if (chosenAction == MOVING) {
            // check if user clicked on current scribble
            draggingScribble = currentScribble.contains(point);
        }

        // remember point of press for drawing or moving
        lastPoint = point;
    }



    public void onMouseDrag(Location point) {
        if (chosenAction == DRAWING) {
            // add line segment to current scribble
            currentScribble =
            new Scribble(new Line(lastPoint, point, canvas),
                currentScribble);
        } else if (chosenAction == MOVING) {
            // move current scribble if dragging it
            if (draggingScribble) {
                currentScribble.move(point.getX() - lastPoint.getX(),
                    point.getY() - lastPoint.getY());
            }
        }
        // update for next move or draw
        lastPoint = point;
    }


    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == setDraw) {
            chosenAction = DRAWING;
        } else if (e.getSource() == setMove) {
            chosenAction = MOVING;
        }
    }
}

Scribble.java

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

/*
 * A very basic recursive data structure to represent
 * a Scribble, augmented with contains, move, and isEmpty
 * methods.
 *
 * Jim Teresco, CSC 252, The College of Saint Rose, Fall 2013
 * Based on similar example from Williams College CS 134.
 * 
 * $Id: Scribble.java 2230 2013-10-27 02:26:10Z terescoj $
 */

// A class to represent a scribble
public class Scribble {
    private Line first;           // an edge line of the scribble
    private Scribble rest;        // the rest of the scribble

    // Our constructor here doesn't actually do any of the
    // drawing - it takes a line that someone else created and
    // which is supposed to be part of the Scribble, and
    // a reference to another Scribble which represents
    // any previous Scribble.
    public Scribble(Line segment, Scribble theRest) {
        first = segment;
        rest = theRest;
    }

    // returns true iff the scribble contains the point
    // Note that things are slightly more complex than some
    // of our other recursive accessors as there are three
    // possibilities: 1) this Scribble is empty, in which
    // case it cannot contain the point, 2) first contains
    // the point, in which case the whole Scribble contains
    // the point, or 3) the answer depends on whether rest
    // (itself a Scribble, hence the recursive call) contains
    // the point
    public boolean contains(Location point) {
        if (isEmpty()) {
            return false;
        } else if (first.contains(point)) {
            return true;
        } else {
            return rest.contains(point);
        }
    }



    // the scribble is moved xOffset in the x direction
    //    and yOffset in the y direction
    public void move(double xOffset, double yOffset) {
        if (!isEmpty()) {
            first.move(xOffset, yOffset);
            rest.move(xOffset, yOffset);
        }
    }

    // returns true iff the list is empty
    public boolean isEmpty() {
        return (first == null);
    }
}