| 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