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}