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

import java.util.ArrayList;

/**
 *  Defines a panel where the user can sketch a curve by dragging the
 *  mouse.  Only one curve can be shown at a time.  When the user clicks
 *  on the panel, the previous curve is discarded, and a new curve is
 *  started.  The curve that the use sketches is drawn along with its
 *  horizontal and vertical reflections, giving a nice, symmetric picture.
 */
public class OneCurve extends JPanel {

   public static void main(String[] args) {
       JFrame window = new JFrame("OneCurve");
       window.setContentPane(new OneCurve());
       window.pack();
       window.setLocation(200,100);
       window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       window.setVisible(true);
   }
   
   private ArrayList<Point> points;  // A list of points on the curve.

   public OneCurve() {
      points = new ArrayList<Point>();  // Create the list, initially empty.
      setPreferredSize( new Dimension(500,500) );
      setBackground(Color.WHITE);
      setBorder( BorderFactory.createLineBorder(Color.GRAY,2) );
      MouseHandler mh = new MouseHandler();
      addMouseListener(mh);
      addMouseMotionListener(mh);
   }
   
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      int w = getWidth();  // The actual current width of this panel.
      int h = getHeight(); // The actual current height of this panel.
      for (int i = 1; i < points.size(); i++) {   // Note:  Start at 1, not 0!
         Point thisPt = points.get(i);   // The i-th point on the curve.
         Point lastPt = points.get(i-1); // The  previous point, number i-1.
         g.drawLine(lastPt.x, lastPt.y, thisPt.x, thisPt.y);           // original curve
         g.drawLine(w-lastPt.x, lastPt.y, w-thisPt.x, thisPt.y);       // horizontal reflection
         g.drawLine(lastPt.x, h-lastPt.y, thisPt.x, h-thisPt.y);       // vertical reflection
         g.drawLine(w-lastPt.x, h-lastPt.y, w-thisPt.x, h-thisPt.y);   // double reflection
      }
   }
   
   private class MouseHandler implements MouseListener, MouseMotionListener {
      boolean dragging;  // Set to true while a drag operation is in progress.
                         // (This is necessary because not all mouse presses
                         // start a drag operation.)
      //int startX, startY;   // The (x,y) coordinates when the drag operation started.
      //int prevX, prevY;    // The previous position of the mouse (from the initial
                           // mousePressed or the previous mouseDragged).
      public void mousePressed(MouseEvent evt) {
         // startX = prevX = evt.getX();  // not used in this application
         // startY = prevY = evt.getY();
         // ... React to mouse press, if appropriate.
         // ... Decide whether to start a drag and, if so, set dragging = true.
         points.clear();  // Get rid of the points on the previously drawn curve.
         points.add( new Point(evt.getX(),evt.getY()) );  // Starting point for the new curve.
         repaint();  // The panel will be redrawn blank.
         dragging = true;
      }
      public void mouseDragged(MouseEvent evt) {
         if (!dragging)
            return;
         int x = evt.getX();
         int y = evt.getY();
         // ... Process a motion from (prevX,prevY) to (x,y).
         points.add( new Point(x,y) );  // The next point on the curve.
         repaint();  // Redraw the panel to show the extended curve.
         // prevX = x;  // (Not used in this application.)
         // prevY = y;
      }
      public void mouseReleased(MouseEvent evt) {
         if (!dragging)
            return;
         // ... Finish the drag operation (if needed).
         dragging = false;
      }
      public void mouseMoved(MouseEvent evt) {
      }
      public void mouseEntered(MouseEvent evt) {
      }
      public void mouseExited(MouseEvent evt) {
      }
      public void mouseClicked(MouseEvent evt) {
      }
   }
   
}

