ErdAttributesNodeLabelModel.java |
1 /**************************************************************************** 2 * This demo file is part of yFiles for Java 2.14. 3 * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28, 4 * 72070 Tuebingen, Germany. All rights reserved. 5 * 6 * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution 7 * of demo files in source code or binary form, with or without 8 * modification, is not permitted. 9 * 10 * Owners of a valid software license for a yFiles for Java version that this 11 * demo is shipped with are allowed to use the demo source code as basis 12 * for their own yFiles for Java powered applications. Use of such programs is 13 * governed by the rights and conditions as set out in the yFiles for Java 14 * license agreement. 15 * 16 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 19 * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 ***************************************************************************/ 28 package demo.view.entityrelationship.painters; 29 import y.base.YList; 30 import y.geom.OrientedRectangle; 31 import y.geom.YDimension; 32 import y.geom.YRectangle; 33 import y.io.graphml.NamespaceConstants; 34 import y.io.graphml.input.DeserializationEvent; 35 import y.io.graphml.input.DeserializationHandler; 36 import y.io.graphml.input.GraphMLParseException; 37 import y.io.graphml.output.GraphMLWriteException; 38 import y.io.graphml.output.SerializationEvent; 39 import y.io.graphml.output.SerializationHandler; 40 import y.io.graphml.output.XmlWriter; 41 import y.layout.NodeLabelCandidate; 42 import y.layout.NodeLabelLayout; 43 import y.layout.NodeLabelModel; 44 import y.layout.NodeLayout; 45 import y.view.NodeLabel; 46 import y.view.NodeRealizer; 47 48 /** 49 * This label model computes the size and placement information for the 50 * attributes label of an ERD entity node. 51 * The area of the attributes label starts at the separator line and fills 52 * the whole lower compartment. 53 */ 54 public class ErdAttributesNodeLabelModel implements NodeLabelModel { 55 56 /** The horizontal distance of the label to the border of the node */ 57 private static final double OFFSET_X = 2; 58 /** The minimal vertical distance of the label to the separator line */ 59 private static final double MIN_OFFSET_Y = 2; 60 /** 61 * The model parameter that contains information about a specific label. 62 * In this case it is an empty class because there is only one possible position 63 * for the attributes label. 64 */ 65 private static final ErdAttributesNodeLabelModelParameter PARAMETER = 66 new ErdAttributesNodeLabelModelParameter(); 67 68 /** 69 * Returns the default parameter of this label model. 70 * @return the default parameter 71 */ 72 public Object getDefaultParameter() { 73 return PARAMETER; 74 } 75 76 /** 77 * Returns the oriented label position and bounds encoded by the given model 78 * parameter. 79 * 80 * @param labelSize The size of the label that should be placed. 81 * @param nodeLayout The layout of the node to which the label belongs. 82 * @param param The model parameter that describes the abstract position of 83 * the label within this model. The parameter must have been generated by 84 * this model. 85 * 86 * @return the oriented label position and bounds. 87 */ 88 public OrientedRectangle getLabelPlacement( 89 final YDimension labelSize, 90 final NodeLayout nodeLayout, 91 final Object param 92 ) { 93 final YRectangle tmp1 = getLabelBox(labelSize, nodeLayout); 94 return new OrientedRectangle(tmp1); 95 } 96 97 /** 98 * Returns a list of candidate positions for the specified node and label data. 99 * 100 * @param nl The label layout for which candidates should be generated. 101 * @param nodeLayout The layout of the node to which the label belongs. 102 * @return a list of candidate positions for the specified node and label data. 103 */ 104 public YList getLabelCandidates( 105 final NodeLabelLayout nl, 106 final NodeLayout nodeLayout 107 ) { 108 final YList candidates = new YList(); 109 final YRectangle box = getLabelBox(nl.getBox(), nodeLayout); 110 candidates.add(new NodeLabelCandidate( 111 box.getLocation(), 112 box, 113 PARAMETER, 114 nl, 115 true)); 116 return candidates; 117 } 118 119 /** 120 * Creates a model parameter that represents the given node label context best 121 * within this model. 122 * The created model parameter represents the closest parameter representation 123 * of the given oriented label bounds that can be achieved within this model. 124 * 125 * @param labelBounds 126 * The bounds of the label for which a parameter representation is sought. 127 * @param nodeLayout 128 * The layout of the node to which the label belongs. 129 * 130 * @return the default parameter 131 */ 132 public Object createModelParameter( 133 final OrientedRectangle labelBounds, 134 final NodeLayout nodeLayout 135 ) { 136 return PARAMETER; 137 } 138 139 140 /** 141 * Computes the size and position of the attributes label. 142 * @param labelSize The size of the label 143 * @param nodeLayout The layout of the node 144 * @return a <code>YRectangle</code> that defines the area of the label box 145 */ 146 private static YRectangle getLabelBox( 147 final YDimension labelSize, 148 final NodeLayout nodeLayout 149 ) { 150 if (nodeLayout instanceof NodeRealizer) { 151 //if ERD style is used, compute the borders of the area under the separator 152 final NodeRealizer nr = (NodeRealizer) nodeLayout; 153 if (ErdNodePainter.useErdStyle(nr)) { 154 final NodeLabel nl = nr.getLabel(); 155 final double sy = ErdNodePainter.separator(nl); 156 157 final double offsetY = Math.max(MIN_OFFSET_Y, nl.getDistance()); 158 159 final double x = nr.getX(); 160 161 final double minX = x + OFFSET_X; 162 final double minY = sy + offsetY; 163 164 return new YRectangle( 165 minX, 166 minY, 167 Math.max(labelSize.width, x + nr.getWidth() - OFFSET_X - minX), 168 Math.max(labelSize.height, nr.getY() + nr.getHeight() - offsetY - minY)); 169 } 170 } 171 172 // if no ERD style is used return a default box 173 return getDefaultBox(labelSize, nodeLayout); 174 } 175 176 /** 177 * Computes a default size and position for the label. 178 * @param labelSize the size of the label 179 * @param nodeLayout the layout of the node 180 * @return a <code>YRectangle</code> that defines the area of the label box 181 */ 182 private static YRectangle getDefaultBox( 183 final YDimension labelSize, 184 final NodeLayout nodeLayout 185 ) { 186 final double w = labelSize.width; 187 final double h = labelSize.height; 188 return new YRectangle( 189 nodeLayout.getX() + (nodeLayout.getWidth() - w) * 0.5, 190 nodeLayout.getY() + (nodeLayout.getHeight() - h) * 0.5, 191 w, 192 h); 193 } 194 195 /** 196 * This parameter is used to provide information for a specific label. 197 * As the attributes label always fills the whole lower compartment of the 198 * entity node, this parameter has no function. However, it is needed to proper 199 * serialization/deserialization. 200 */ 201 private static final class ErdAttributesNodeLabelModelParameter { 202 } 203 204 205 /** 206 * This handler provides a serialization/deserialization functionality for the 207 * nodes in ERD style. 208 * 209 * It makes sure that the attributes label can be loaded/stored from/to GraphML properly. 210 */ 211 public static final class Handler 212 implements SerializationHandler, DeserializationHandler { 213 214 /** The GraphML element name for the ERD label model */ 215 private static final String MODEL_NAME = "ErdAttributesNodeLabelModel"; 216 /** The GraphML element name for the parameter of the ERD label model */ 217 private static final String PARAM_NAME = "ErdAttributesNodeLabelModelParameter"; 218 219 /** 220 * Handles the deserialization of the ERD attributes label. 221 * @param event an event that contains all data that is needed for deserialization. 222 * @throws GraphMLParseException 223 */ 224 public void onHandleDeserialization( 225 final DeserializationEvent event 226 ) throws GraphMLParseException { 227 final org.w3c.dom.Node node = event.getXmlNode(); 228 if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE && 229 NamespaceConstants.YFILES_JAVA_NS.equals(node.getNamespaceURI())) { 230 final String ln = node.getLocalName(); 231 if (MODEL_NAME.equals(ln)) { 232 event.setResult(new ErdAttributesNodeLabelModel()); 233 } else if (PARAM_NAME.equals(ln)) { 234 event.setResult(PARAMETER); 235 } 236 } 237 } 238 239 /** 240 * Handles the serialization of the ERD attributes label. 241 * @param event an event that contains all data that is needed for serialization. 242 * @throws GraphMLWriteException 243 */ 244 public void onHandleSerialization( 245 final SerializationEvent event 246 ) throws GraphMLWriteException { 247 final Object item = event.getItem(); 248 if (item instanceof ErdAttributesNodeLabelModel) { 249 final XmlWriter writer = event.getWriter(); 250 writer.writeStartElement(MODEL_NAME, NamespaceConstants.YFILES_JAVA_NS); 251 writer.writeEndElement(); 252 event.setHandled(true); 253 } else if (item == PARAMETER) { 254 final XmlWriter writer = event.getWriter(); 255 writer.writeStartElement(PARAM_NAME, NamespaceConstants.YFILES_JAVA_NS); 256 writer.writeEndElement(); 257 event.setHandled(true); 258 } 259 } 260 } 261 } 262