What follows is the highlighted source code with comments. You can also download this file directly: InteractionDemo.java.
/* * This work by W. Patrick Hooper is free of known copyright restrictions. * The work is in the public domain. * * Author's website: <a href="http://wphooper.com">http://wphooper.com</a>. */ import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.util.Iterator; import java.util.LinkedList; import javax.swing.JFrame; import javax.swing.JPanel; /** This class was created to demonstrate how a graphical program can interact * with the user's mouse. * * The program places a disk centered at every mouse click of the user. The * user can interact with the disks by dragging them around. * * @author pat */ public class InteractionDemo extends JPanel implements MouseListener, MouseMotionListener { private static final int R = 20; // Radii of disks // This list records the places the user clicks. private LinkedList<Point2D> click_locations=new LinkedList<Point2D>(); public InteractionDemo() { setBackground(Color.WHITE); // Make the background color white // Necessary for mouse interaction: addMouseListener(this); addMouseMotionListener(this); } ///// DRAWING /** * Draw the disks. */ @Override public void paintComponent(Graphics gfx) { // This stuff is standard, and should be in any paintComponent method. super.paintComponent(gfx); Graphics2D g = (Graphics2D) gfx; g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(Color.BLACK); g.drawString("Click somewhere to add a disk. You can also drag disks.", 10, 20); g.setStroke(new BasicStroke(2)); double hue = 0; // for picking different colors. for (Point2D pt : click_locations) { Ellipse2D e = new Ellipse2D.Double(pt.getX() - R, pt.getY() - R, 2 * R, 2 * R); g.setColor(Color.getHSBColor((float) hue, 1f, 1f)); g.fill(e); g.setColor(Color.BLACK); g.draw(e); hue = hue + (Math.sqrt(5) - 1) / 2; hue = hue - Math.floor(hue); } } ///// MOUSE INTERACTION // Implementation of MouseListener @Override public void mouseClicked(MouseEvent me) { click_locations.addLast(me.getPoint()); repaint(); } @Override public void mouseEntered(MouseEvent me) { } @Override public void mouseExited(MouseEvent me) { } boolean disk_selected=false; int selected_disk_index=0; Point2D last_mouse_location; @Override public void mousePressed(MouseEvent me) { Iterator<Point2D> it=click_locations.descendingIterator(); int index=click_locations.size()-1; while (it.hasNext()) { if (me.getPoint().distance(it.next())<R) { disk_selected=true; selected_disk_index=index; last_mouse_location=me.getPoint(); break; // quit the while loop. } index = index-1; } } @Override public void mouseReleased(MouseEvent me) { disk_selected=false; } // Implementation of MouseMotionListener @Override public void mouseDragged(MouseEvent me) { if (disk_selected) { Point2D current_center=click_locations.get(selected_disk_index); Point2D new_center=new Point2D.Double( current_center.getX()+me.getX()-last_mouse_location.getX(), current_center.getY()+me.getY()-last_mouse_location.getY()); click_locations.set(selected_disk_index, new_center); last_mouse_location=me.getPoint(); repaint(); } } @Override public void mouseMoved(MouseEvent me) { } public static void main(String[] args) { // Construct a new window: JFrame frame = new JFrame("InteractionDemo"); // Dimensions of the window in pixels: frame.setSize(640, 480); // Quit the program when the window is closed: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // The window will contain only our panel: frame.add(new InteractionDemo()); // Make the window visible: frame.setVisible(true); } }