package com.horstmann.violet.product.diagram.classes.node; import java.awt.*; import java.util.*; import java.util.List; import com.horstmann.violet.framework.graphics.Separator; import com.horstmann.violet.framework.graphics.content.*; import com.horstmann.violet.framework.graphics.content.VerticalLayout; import com.horstmann.violet.framework.graphics.shape.ContentInsideRectangle; import com.horstmann.violet.product.diagram.classes.ClassDiagramConstant; import com.horstmann.violet.product.diagram.property.text.decorator.*; import com.horstmann.violet.product.diagram.common.node.ColorableNode; import com.horstmann.violet.product.diagram.property.text.LineText; import com.horstmann.violet.product.diagram.abstracts.node.INode; import com.horstmann.violet.product.diagram.property.text.MultiLineText; import com.horstmann.violet.product.diagram.property.text.SingleLineText; /** * A class node in a class diagram. */ public class ClassNode extends ColorableNode { /** * Construct a class node with a default size */ public ClassNode() { super(); name = new SingleLineText(NAME_CONVERTER); name.setAlignment(LineText.CENTER); attributes = new MultiLineText(PROPERTY_CONVERTER); methods = new MultiLineText(PROPERTY_CONVERTER); createContentStructure(); } protected ClassNode(ClassNode node) throws CloneNotSupportedException { super(node); name = node.name.clone(); attributes = node.attributes.clone(); methods = node.methods.clone(); createContentStructure(); } @Override protected void beforeReconstruction() { super.beforeReconstruction(); if(null == name) { name = new SingleLineText(); } if(null == attributes) { attributes = new MultiLineText(); } if(null == methods) { methods = new MultiLineText(); } name.reconstruction(NAME_CONVERTER); attributes.reconstruction(PROPERTY_CONVERTER); methods.reconstruction(PROPERTY_CONVERTER); name.setAlignment(LineText.CENTER); } @Override protected INode copy() throws CloneNotSupportedException { return new ClassNode(this); } @Override protected void createContentStructure() { TextContent nameContent = new TextContent(name); nameContent.setMinHeight(MIN_NAME_HEIGHT); nameContent.setMinWidth(MIN_WIDTH); TextContent attributesContent = new TextContent(attributes); TextContent methodsContent = new TextContent(methods); VerticalLayout verticalGroupContent = new VerticalLayout(); verticalGroupContent.add(nameContent); verticalGroupContent.add(attributesContent); verticalGroupContent.add(methodsContent); separator = new Separator.LineSeparator(getBorderColor()); verticalGroupContent.setSeparator(separator); ContentInsideShape contentInsideShape = new ContentInsideRectangle(verticalGroupContent); setBorder(new ContentBorder(contentInsideShape, getBorderColor())); setBackground(new ContentBackground(getBorder(), getBackgroundColor())); setContent(getBackground()); setTextColor(super.getTextColor()); } @Override public void setBorderColor(Color borderColor) { if(null != separator) { separator.setColor(borderColor); } super.setBorderColor(borderColor); } @Override public void setTextColor(Color textColor) { name.setTextColor(textColor); attributes.setTextColor(textColor); methods.setTextColor(textColor); super.setTextColor(textColor); } @Override public String getToolTip() { return ClassDiagramConstant.CLASS_DIAGRAM_RESOURCE.getString("tooltip.class_node"); } /** * Sets the name property value. * * @param newValue the class name */ public void setName(LineText newValue) { name.setText(newValue); } /** * Gets the name property value. * * @return the class name */ public LineText getName() { return name; } /** * Sets the attributes property value. * * @param newValue the attributes of this class */ public void setAttributes(LineText newValue) { attributes.setText(newValue); } /** * Gets the attributes property value. * * @return the attributes of this class */ public LineText getAttributes() { return attributes; } /** * Sets the methods property value. * * @param newValue the methods of this class */ public void setMethods(LineText newValue) { methods.setText(newValue); } /** * Gets the methods property value. * * @return the methods of this class */ public LineText getMethods() { return methods; } private SingleLineText name; private MultiLineText attributes; private MultiLineText methods; private transient Separator separator; private static final int MIN_NAME_HEIGHT = 45; private static final int MIN_WIDTH = 100; private static final String STATIC = "<<static>>"; private static final String ABSTRACT = "«abstract»"; private static final String[][] SIGNATURE_REPLACE_KEYS = { { "public ", "+ " }, { "package ", "~ " }, { "protected ", "# " }, { "private ", "- " }, { "property ", "/ " } }; private static final List<String> STEREOTYPES = Arrays.asList( "«Utility»", "«Type»", "«Metaclass»", "«ImplementationClass»", "«Focus»", "«Entity»", "«Control»", "«Boundary»", "«Auxiliary»", ABSTRACT ); private static final LineText.Converter NAME_CONVERTER = new LineText.Converter() { @Override public OneLineText toLineString(String text) { OneLineText controlText = new OneLineText(text); OneLineText lineString = new LargeSizeDecorator(controlText); if(controlText.contains(ABSTRACT)) { lineString = new ItalicsDecorator(lineString); } for(String stereotype : STEREOTYPES) { if(controlText.contains(stereotype)) { lineString = new PrefixDecorator(new RemoveSentenceDecorator( lineString, stereotype), String.format("<center>%s</center>", stereotype) ); } } return lineString; } }; private static final LineText.Converter PROPERTY_CONVERTER = new LineText.Converter() { @Override public OneLineText toLineString(String text) { OneLineText lineString = new OneLineText(text); if(lineString.contains(STATIC)) { lineString = new UnderlineDecorator(new RemoveSentenceDecorator(lineString, STATIC)); } for(String[] signature : SIGNATURE_REPLACE_KEYS) { lineString = new ReplaceSentenceDecorator(lineString, signature[0], signature[1]); } return lineString; } }; }