File "LineCanvas.java"

Full Path: /home/analogde/www/Ebook/Informatique/JAVA/Source/LineCanvas.java
File size: 3.99 KB
MIME-type: text/x-java
Charset: utf-8

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.event.MouseInputAdapter;

/**
 * This class represents a drawing surface that can draw lines between points
 * where the user clicks the mouse.
 * This version also responds to various keyboard events to change colors,
 * scale, rotate, and translate the drawings on the screen.
 * 
 * @author Marty Stepp
 * @version CSE 331 Spring 2011, 05/11/2011
 */
public class LineCanvas extends JComponent {
	private static final long serialVersionUID = 1L;
	
	private List<Point> clicks; // past points the user has clicked
	private Point mousePosition; // mouse pointer's current position
	private Color color;
	private int yOffset;
	private double scale;
	private double rotation;
	
	/**
	 * Constructs a new empty canvas with no lines.
	 */
	public LineCanvas() {
		clicks = new ArrayList<Point>();
		mousePosition = null;
		color = Color.BLACK;
		yOffset = 0;
		scale = 1.0;
		
		// listen to mouse events
		LineClickListener listener = new LineClickListener();
		addMouseListener(listener);
		addMouseMotionListener(listener);
		addKeyListener(new LineKeyListener());
		this.setFocusable(true);
	}
	
	/**
	 * Draws all previously touched points and lines on this canvas.
	 */
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		
		g2.setStroke(new BasicStroke(3));

		// apply transformations based on past key presses
		g2.translate(0, yOffset);
		g2.scale(scale, scale);
		g2.rotate(rotation);
		
		// draw previously clicked points as circles with lines between
		g2.setColor(color);
		Point prev = null;
		for (Point p : clicks) {
			Ellipse2D dot = new Ellipse2D.Double(p.getX(), p.getY(), 5, 5);
			g2.fill(dot);
			
			if (prev != null) {
				// line between previous point and current point
				Line2D line = new Line2D.Double(prev, p);
				g2.draw(line);
			}
			
			prev = p;
		}
		
		// draw a hovering red line to the mouse's current position, if
		// necessary
		if (mousePosition != null && !clicks.isEmpty()) {
			Point lastClick = clicks.get(clicks.size() - 1);
			Line2D line = new Line2D.Double(lastClick, mousePosition);
			g2.setColor(Color.RED);
			g2.draw(line);
		}
	}
	
	// This listener handles mouse events in the canvas.
	private class LineClickListener extends MouseInputAdapter {
		/**
		 * Handles mouse clicks by drawing a new line to the point clicked.
		 */
		public void mouseClicked(MouseEvent e) {
			// System.out.println("The mouse was clicked");
			
			// If the user double-clicks, add a point to draw a line
			if (e.getClickCount() >= 2) {
				clicks.add(e.getPoint());
				repaint();
			}
		}
		
		/**
		 * Handles mouse clicks by showing a red hovering line from the previous
		 * click point to the most recent point clicked.
		 */
		public void mouseMoved(MouseEvent e) {
			mousePosition = e.getPoint();
			repaint();
		}
	}
	
	// This listener handles mouse events in the canvas.
	private class LineKeyListener extends KeyAdapter {
		/**
		 * Handles key presses in the canvas by allowing the user to select
		 * colors or apply transformations.
		 */
		public void keyPressed(KeyEvent event) {
			System.out.println("A key was pressed by " + event.getSource());
			if (event.getKeyChar() == 'c') {
				color = JColorChooser.showDialog(null, "Pick a color", Color.BLACK);
				repaint();
			} else if (event.getKeyCode() == KeyEvent.VK_DOWN) {
				// down arrow; translate down
				yOffset += 5;
				repaint();
			} else if (event.getKeyChar() == '+') {
				// + key scales up slightly
				scale += 0.1;
				repaint();
			} else if (event.getKeyChar() == 'r') {
				// r key rotates slightly
				rotation += Math.PI / 100;  // radians
				repaint();
			}
		}
	}
}