import javax.swing.*; 
import java.awt.*;
import java.util.*;
import java.awt.event.*; 

class Two extends JFrame {
  Two() {
    Three three = new Three(15);
    this.getContentPane().add( three ); 
    this.setVisible(true); 
    this.setSize(400, 500); 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     
  }
  public static void main(String[] args) {
    JFrame t = new Two(); 
  }
}

class Point {
  int x, y;
  Point(int x, int y) {
    this.x = x; 
    this.y = y; 
  }
}

abstract class Shape {
  Point topLeft; 
  Color color; 
  Shape(Point where, Color what) {
    this.topLeft = where;
    this.color = what; 
  }
  abstract boolean contains(Point mouse); 
  abstract void draw(Graphics g); 
  abstract void moveTo(Point mouse); 
}

class Rectangle extends Shape {
  int width, height; 
  Rectangle(Point location, int w, int h, Color c) {
    super(location, c);
    this.width = w;
    this.height = h; 
  } 
  void draw(Graphics g) {
    g.setColor(this.color);
    g.fillRect(this.topLeft.x, this.topLeft.y, this.width, this.height);
    g.setColor(Color.BLACK);
    g.drawRect(this.topLeft.x, this.topLeft.y, this.width, this.height);

  }
  boolean contains(Point where) {
    int dx = where.x - topLeft.x; 
    int dy = where.y - topLeft.y; 
    return 0 <= dx && dx < this.width && 0 <= dy && dy <= this.height; 
  }
  void moveTo(Point where) {
    this.topLeft = where; 
  }
}

class Three extends JComponent implements MouseListener, MouseMotionListener {
  public void mouseMoved(MouseEvent e) { } 
  public void mouseDragged(MouseEvent e) { 
    System.out.println( e.getX() + ", " + e.getY() );

    if (current != null) { 
      this.current.moveTo( new Point(e.getX(), e.getY()) );
      System.out.println( current ); 
      // is that it? no, we need to also repaint();
      repaint(); 
    }

  } 
  public void mouseClicked(MouseEvent e) { } 

  Shape current; 

  public void mousePressed(MouseEvent e) { 
    System.out.println( "Mouse pressed..." ); 
    Point mouse = new Point(e.getX(), e.getY()); 
    for (Shape r : this.shapes) {
      if (r.contains(mouse)) {
        this.current = r;
        break; 
      } 
    } 
  } 
  public void mouseReleased(MouseEvent e) { 
    this.current = null; 
  } 
  public void mouseEntered(MouseEvent e) { } 
  public void mouseExited(MouseEvent e) { } 

  ArrayList<Shape> shapes; 

  Three(int size) {

    this.addMouseMotionListener( this ); 
    this.addMouseListener( this ); 

    this.shapes = new ArrayList<Shape>(); 
    for (int i = 0; i < size; i++) {
      Point where = new Point((int)(Math.random() * 300 + 50), 
                              (int)(Math.random() * 300 + 50)); 
      int width = (int)(Math.random() * 80 + 20);
      int height = (int)(Math.random() * 80 + 20); 
      int red = (int) (Math.random() * 255); 
      int green = (int) (Math.random() * 255); 
      int blue = (int) (Math.random() * 255); 
      Color color = new Color(red, green, blue);
      this.shapes.add(new Rectangle(where, width, height, color)); 
    } 
  }  
  public void paintComponent(Graphics g) {
    for (Shape r : this.shapes) 
      r.draw( g ); 
  } 
}