001package horstmann.ch08_umleditor;
002import java.awt.Graphics2D;
003import java.awt.geom.Rectangle2D;
004
005/**
006   A class node in a class diagram.
007 */
008@SuppressWarnings("serial")
009public class ClassNode extends RectangularNode
010{
011        /**
012      Construct a class node with a default size
013         */
014        public ClassNode()
015        {
016                name = new MultiLineString();
017                name.setSize(MultiLineString.LARGE);
018                attributes = new MultiLineString();
019                attributes.setJustification(MultiLineString.LEFT);
020                methods = new MultiLineString();
021                methods.setJustification(MultiLineString.LEFT);
022                setBounds(new Rectangle2D.Double(0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT));
023                midHeight = DEFAULT_COMPARTMENT_HEIGHT;
024                botHeight = DEFAULT_COMPARTMENT_HEIGHT;
025        }
026
027        public void draw(Graphics2D g2)
028        {
029                layout(g2);
030                Rectangle2D top = new Rectangle2D.Double(getBounds().getX(),
031                                getBounds().getY(), getBounds().getWidth(),
032                                getBounds().getHeight() - midHeight - botHeight);
033                g2.draw(top);
034                name.draw(g2, top);
035                Rectangle2D mid = new Rectangle2D.Double(top.getX(),
036                                top.getMaxY(), top.getWidth(), midHeight);
037                g2.draw(mid);
038                attributes.draw(g2, mid);
039                Rectangle2D bot = new Rectangle2D.Double(top.getX(),
040                                mid.getMaxY(), top.getWidth(), botHeight);
041                g2.draw(bot);
042                methods.draw(g2, bot);
043        }
044
045        /**
046      Recomputes the layout of this node.
047      @param g2 the graphics context
048         */
049        public void layout(Graphics2D g2)
050        {
051                Rectangle2D min = new Rectangle2D.Double(0, 0,
052                                DEFAULT_WIDTH, DEFAULT_COMPARTMENT_HEIGHT);
053                Rectangle2D top = name.getBounds(g2);
054                top.add(min);
055                Rectangle2D mid = attributes.getBounds(g2);
056                Rectangle2D bot = methods.getBounds(g2);
057
058                midHeight = mid.getHeight();
059                botHeight = bot.getHeight();
060                if (midHeight == 0 && botHeight == 0)
061                {
062                        top.add(new Rectangle2D.Double(0, 0,
063                                        DEFAULT_WIDTH,
064                                        3 * DEFAULT_COMPARTMENT_HEIGHT));
065                }
066                else
067                {
068                        mid.add(min);
069                        bot.add(min);
070                        midHeight = mid.getHeight();
071                        botHeight = bot.getHeight();
072                }
073
074                Rectangle2D b = new Rectangle2D.Double(
075                                getBounds().getX(), getBounds().getY(),
076                                Math.max(top.getWidth(), Math.max(mid.getWidth(),
077                                                bot.getWidth())),
078                                top.getHeight() + midHeight + botHeight);
079                setBounds(b);
080        }
081
082        /**
083      Sets the name property value.
084      @param newValue the class name
085         */
086        public void setName(MultiLineString newValue)
087        {
088                name = newValue;
089        }
090
091        /**
092      Gets the name property value.
093      @return the class name
094         */
095        public MultiLineString getName()
096        {
097                return name;
098        }
099
100        /**
101      Sets the attributes property value.
102      @param newValue the attributes of this class
103         */
104        public void setAttributes(MultiLineString newValue)
105        {
106                attributes = newValue;
107        }
108
109        /**
110      Gets the attributes property value.
111      @return the attributes of this class
112         */
113        public MultiLineString getAttributes()
114        {
115                return attributes;
116        }
117
118        /**
119      Sets the methods property value.
120      @param newValue the methods of this class
121         */
122        public void setMethods(MultiLineString newValue)
123        {
124                methods = newValue;
125        }
126
127        /**
128      Gets the methods property value.
129      @return the methods of this class
130         */
131        public MultiLineString getMethods()
132        {
133                return methods;
134        }
135
136        public Object clone()
137        {
138                ClassNode cloned = (ClassNode) super.clone();
139                cloned.name = (MultiLineString) name.clone();
140                cloned.methods = (MultiLineString) methods.clone();
141                cloned.attributes = (MultiLineString) attributes.clone();
142                return cloned;
143        }
144
145        private double midHeight;
146        private double botHeight;
147        private MultiLineString name;
148        private MultiLineString attributes;
149        private MultiLineString methods;
150
151        private static int DEFAULT_COMPARTMENT_HEIGHT = 20;
152        private static int DEFAULT_WIDTH = 80;
153        private static int DEFAULT_HEIGHT = 60;
154}