This program allows users to drag shapes around the screen. Let's take a look at how it's implemented.

First, we generate 10 GOvals and place them randomly about the canvas. This happens in the method addRandomObjects( ). Notice how we use the constants NUM_RANDOM_OBJECTS and OBJECT_SIZE instead of the magic numbers 10 and 50 when creating the objects.

Once we've added the random objects, we tell the program to listen for mouse events like mouse clicks and drags with the addMouseListeners( ) method. We also specify what the program should do in the event of a mouse click or drag by implementing the mousePressed and mouseDragged methods. Because we can't pass variables other than the MouseEvent to the mouseDragged method, we need an instance variable to keep track of which oval was clicked. Ask one of the teachers to explain why we need an instance variable here if it doesn't make sense.

Solution

/**
 * Class: SuchADrag
 * -----------------
 * A program that creates a collection of objects on the screen, then lets
 * the user click and drag them around.
 */
public class SuchADrag extends GraphicsProgram {
    public void run() {
        addRandomObjects();
        addMouseListeners();
    }

    /* The object which has been selected for dragging. */
    private GObject selectedObject;

    /**
     * Selects the object under the mouse cursor when the mouse is pressed.
     * If nothing is found, that's okay - we'll set selectedObject to null.
     */
    public void mousePressed(MouseEvent e) {
        selectedObject = getElementAt(e.getX(), e.getY());
    }

    /**
     * Repositions the dragged object to the mouse's location when the mouse
     * is moved.
     */
    public void mouseDragged(MouseEvent e) {
        /* If there is something to drag at all, go move it. */
        if (selectedObject != null) {
            double newX = e.getX() - selectedObject.getWidth() / 2.0;
            double newY = e.getY() - selectedObject.getHeight() / 2.0;
            selectedObject.setLocation(newX, newY);
        }
    }

    /* * * * * Code for adding random objects below this point. * * * * */

    /* The number of objects to add. */
    private static final int NUM_RANDOM_OBJECTS = 10;

    /* The size of each random object. */
    private static final double OBJECT_SIZE = 50;

    /**
     * Adds a bunch of random objects to the screen.
     */
    private void addRandomObjects() {
        for (int i = 0; i < NUM_RANDOM_OBJECTS; i++) {
            addRandomObject();
        }
    }

    /**
     * Adds a single random object to the screen.
     */
    private void addRandomObject() {
        RandomGenerator rgen = RandomGenerator.getInstance();

        GOval object = new GOval(rgen.nextDouble(0, getWidth() - OBJECT_SIZE),
                             rgen.nextDouble(0, getHeight() - OBJECT_SIZE),
                             OBJECT_SIZE, OBJECT_SIZE);
        object.setFilled(true);
        object.setColor(Color.BLUE);
        add(object);
    }
}