``` 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 ``` ```package horstmann.ch08_graphed; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; /** A circular node that is filled with a color. */ @SuppressWarnings("serial") public class CircleNode implements Node { /** Construct a circle node with a given size and color. @param aColor the fill color */ public CircleNode(Color aColor) { size = DEFAULT_SIZE; x = 0; y = 0; color = aColor; } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException exception) { return null; } } public void draw(Graphics2D g2) { Ellipse2D circle = new Ellipse2D.Double( x, y, size, size); Color oldColor = g2.getColor(); g2.setColor(color); g2.fill(circle); g2.setColor(oldColor); g2.draw(circle); } public void translate(double dx, double dy) { x += dx; y += dy; } public boolean contains(Point2D p) { Ellipse2D circle = new Ellipse2D.Double( x, y, size, size); return circle.contains(p); } public Rectangle2D getBounds() { return new Rectangle2D.Double( x, y, size, size); } public Point2D getConnectionPoint(Point2D other) { double centerX = x + size / 2; double centerY = y + size / 2; double dx = other.getX() - centerX; double dy = other.getY() - centerY; double distance = Math.sqrt(dx * dx + dy * dy); if (distance == 0) return other; else return new Point2D.Double( centerX + dx * (size / 2) / distance, centerY + dy * (size / 2) / distance); } private double x; private double y; private double size; private Color color; private static final int DEFAULT_SIZE = 20; } ```