001package horstmann.ch08_graphed2;
002import java.awt.Color;
003import java.awt.Graphics2D;
004import java.awt.geom.Ellipse2D;
005import java.awt.geom.Point2D;
006import java.awt.geom.Rectangle2D;
007
008/**
009   A circular node that is filled with a color.
010 */
011@SuppressWarnings("serial")
012public class CircleNode implements Node
013{
014        /**
015      Construct a circle node with a given size and color.
016      @param aColor the fill color
017         */
018        public CircleNode(Color aColor)
019        {
020                size = DEFAULT_SIZE;
021                x = 0;
022                y = 0;
023                color = aColor;
024        }
025
026        public void setColor(Color aColor)
027        {
028                color = aColor;
029        }
030
031        public Color getColor()
032        {
033                return color;
034        }
035
036        public Object clone()
037        {
038                try
039                {
040                        return super.clone();
041                }
042                catch (CloneNotSupportedException exception)
043                {
044                        return null;
045                }
046        }
047
048        public void draw(Graphics2D g2)
049        {
050                Ellipse2D circle = new Ellipse2D.Double(
051                                x, y, size, size);
052                Color oldColor = g2.getColor();
053                g2.setColor(color);
054                g2.fill(circle);
055                g2.setColor(oldColor);
056                g2.draw(circle);
057        }
058
059        public void translate(double dx, double dy)
060        {
061                x += dx;
062                y += dy;
063        }
064
065        public boolean contains(Point2D p)
066        {
067                Ellipse2D circle = new Ellipse2D.Double(
068                                x, y, size, size);
069                return circle.contains(p);
070        }
071
072        public Rectangle2D getBounds()
073        {
074                return new Rectangle2D.Double(
075                                x, y, size, size);
076        }
077
078        public Point2D getConnectionPoint(Point2D other)
079        {
080                double centerX = x + size / 2;
081                double centerY = y + size / 2;
082                double dx = other.getX() - centerX;
083                double dy = other.getY() - centerY;
084                double distance = Math.sqrt(dx * dx + dy * dy);
085                if (distance == 0) return other;
086                else return new Point2D.Double(
087                                centerX + dx * (size / 2) / distance,
088                                centerY + dy * (size / 2) / distance);
089        }
090
091        private double x;
092        private double y;
093        private double size;
094        private Color color;
095        private static final int DEFAULT_SIZE = 20;
096}