Mouser.java

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*; // for Shape2D
import java.util.Random;


/**
Demonstrates using the mouse to drag objects.
*/
public class Mouser extends JFrame
{
    public static void main(String argv[])
    {
        Mouser f = new Mouser();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.show();
    }

    public Mouser()
    {
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension ss = kit.getScreenSize();

        // Window is 3/4 of screen size, centered.
        setSize(3*ss.width/4,3*ss.height/4);
        setLocation(ss.width/8,ss.height/8);

        setTitle("CISC370-011 -- Mouse motion");

        SwingPanel03 sp = new SwingPanel03(NSHAPES);
        Container contentPane = getContentPane();
        contentPane.add(sp);
    }

    private static final int NSHAPES = 12;
}


class SwingPanel03 extends JPanel
{
    public SwingPanel03(int nshapes)
    {
        this.nshapes = nshapes;
        addMouseListener(new MyClicker());
        addMouseMotionListener(new MyDragger());
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        // The first time this panel is instantiated, create an 
        // array of random shapes.
        if (shapes == null) {
            double xmin = 0.0;
            double ymin = 0.0;
            double xmax = (double)getWidth();
            double ymax = (double)getHeight();
            shapes = new ShapeEntry[nshapes];
            for (int i=0; i<shapes.length; i++) {
                shapes[i] = new ShapeEntry(xmin,ymin,xmax,ymax);
                }
            }

        setBackground(Color.WHITE);
        for (int i=0; i<shapes.length; i++)
            shapes[i].paintMe(g);
    }

    private class MyDragger extends MouseMotionAdapter
    {
        public void mouseDragged(MouseEvent e)
        {
            if (curShape != null) {
                curShape.moveTo(e.getX()-xOff,e.getY()-yOff);
                repaint();
                }
        }
    }

    private class MyClicker extends MouseAdapter
    {
        public void mousePressed(MouseEvent e)
        {
            double x = e.getX();
            double y = e.getY();
            // Look through the shape array, backward.
            for (int i=shapes.length-1; i>=0; i--)
                if (shapes[i].contains(x,y)) {
                    curShape = shapes[i];
                    // If we find the shape, save the offset between
                    // where we clicked and the shape's base location.
                    xOff = x - curShape.getX();
                    yOff = y - curShape.getY();
                    break;
                    }
        }

        public void mouseReleased(MouseEvent e)
        {
            curShape = null;
        }
    }

    private class ShapeEntry
    {
        public ShapeEntry(
            double xmin,double ymin,
            double xmax,double ymax)
        {
            // Window sizes.
            double xwin = xmax - xmin;
            double ywin = ymax - ymin;
            // Size between 10 pixels and 1/2 of window height.
            double w = 10.0 + r.nextDouble() * (0.5*xwin - 10.0);
            double h = 10.0 + r.nextDouble() * (0.5*ywin - 10.0);
            // Location random (but at least half of shape on window).
            double x = xmin + -w/2.0 + r.nextDouble()*xwin;
            double y = ymin + -h/2.0 + r.nextDouble()*ywin;

            shape = new Rectangle2D.Double(x,y,w,h);
            color = new Color(
                r.nextInt(256),
                r.nextInt(256),
                r.nextInt(256));
        }

        public void moveTo(double newx,double newy)
        {
            shape.setRect(newx,newy,
                shape.getWidth(),shape.getHeight());
        }

        public double getX() 
            { return shape.getX(); }
        public double getY() 
            { return shape.getY(); }
        public boolean contains(double x,double y)
            { return shape.contains(x,y); }

        public void paintMe(Graphics g)
        {
            Graphics2D g2 = (Graphics2D)g;
            g2.setPaint(color);
            g2.fill(shape);
        }

        Rectangle2D shape = null;
        Color color = null;
    }

    int nshapes = 0;
    private static Random r = new Random();
    private ShapeEntry shapes[] = null;
    private ShapeEntry curShape = null; // Which one are we dragging?
    private double xOff,yOff; // Offset to click point.
}