Computer Science 252
Problem Solving with Java
Spring 2014, The College of Saint Rose
RecScribbler Demo
A working demo of RecScribbler will appear below. Click inside the applet to interact with it.
RecScribbler BlueJ Project
Click here to download a BlueJ project for RecScribbler.
RecScribbler Source Code
The Java source code for RecScribbler is below. Click on a file name to download it.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
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 all of the Scribbles which are
* stored in another recursive structure. We also added
* setColor and clear capabilities.
*
* Jim Teresco, CSC 252, The College of Saint Rose, Fall 2013
* Based on similar example from Williams College CS 134.
*
* $Id: RecScribbler.java 2249 2013-11-07 16:20:52Z terescoj $
*/
public class RecScribbler 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;
private static final int COLORING = 3;
// the current scribble
private Scribble currentScribble;
// the list of all Scribble objects
private ScribbleList allScribbles;
// stores last point for drawing or dragging
private Location lastPoint;
// the scribble that has been selected for moving, if any
// is null if not
private Scribble draggingScribble;
// the scribble we selected for other actions (coloring)
private Scribble selectedScribble;
// buttons that allow user to select modes
private JButton setDraw, setMove, setColor, clearButton;
// the current mode -- drawing by default
private int chosenAction = DRAWING;
// our Random
private Random r;
public void begin() {
// create the user interface components
Container contentPane = getContentPane();
setDraw = new JButton("Draw");
setMove = new JButton("Move");
setColor = new JButton("Set Color");
clearButton = new JButton("Clear");
JPanel buttonPanel = new JPanel();
buttonPanel.add(setDraw);
buttonPanel.add(setMove);
buttonPanel.add(setColor);
buttonPanel.add(clearButton);
contentPane.add(buttonPanel, BorderLayout.SOUTH);
// add listeners
setDraw.addActionListener(this);
setMove.addActionListener(this);
setColor.addActionListener(this);
clearButton.addActionListener(this);
contentPane.validate();
// make the current scribble empty
currentScribble = new Scribble(null, null);
// create our empty list
allScribbles = new ScribbleList(null, null);
// not dragging to start
draggingScribble = null;
// set up random
r = new Random();
}
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 = allScribbles.whichContains(point);
}
else if (chosenAction == COLORING) {
// find which one contains the point, if any
selectedScribble = allScribbles.whichContains(point);
if (selectedScribble != null) {
Color c = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
selectedScribble.setColor(c);
}
}
// 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 != null) {
draggingScribble.move(point.getX() - lastPoint.getX(),
point.getY() - lastPoint.getY());
}
}
// update for next move or draw
lastPoint = point;
}
public void onMouseRelease(Location point) {
if (chosenAction == DRAWING) {
allScribbles = new ScribbleList(currentScribble, allScribbles);
}
draggingScribble = null;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == setDraw) {
chosenAction = DRAWING;
}
else if (e.getSource() == setMove) {
chosenAction = MOVING;
}
else if (e.getSource() == setColor) {
chosenAction = COLORING;
}
else if (e.getSource() == clearButton) {
// clear the canvas
canvas.clear();
// replace our ScribbleList with an empty one
allScribbles = new ScribbleList(null, null);
}
}
}
import java.awt.*;
import objectdraw.*;
/*
* A very basic recursive data structure to represent
* a Scribble, augmented with contains, move, and isEmpty
* methods. Now with setColor!
*
* Jim Teresco, CSC 252, The College of Saint Rose, Fall 2013
* Based on similar example from Williams College CS 134.
*
* $Id: Scribble.java 2249 2013-11-07 16:20:52Z 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);
}
// set the color of this Scribble
public void setColor(Color c) {
if (!isEmpty()) {
first.setColor(c);
rest.setColor(c);
}
}
}
/**
* A list of Scribbles!
*
* @author Jim Teresco and CSC 252 class, Fall 2013
*/
import objectdraw.*;
import java.awt.*;
public class ScribbleList {
private Scribble first;
private ScribbleList rest;
public ScribbleList(Scribble first, ScribbleList rest){
this.first = first;
this.rest = rest;
}
// return the Scribble in the list that contains the given point
// and null if no Scribble contains the point
public Scribble whichContains(Location point) {
// an empty ScribbleList can't have a Scribble
// that contains the point
if (first == null) return null;
// does the first Scribble contain the point?
if (first.contains(point)) return first;
return rest.whichContains(point);
}
}