1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.scenegraph.g2d.nodes;
14 import java.awt.Color;
15 import java.awt.Graphics2D;
16 import java.awt.Shape;
17 import java.awt.Stroke;
18 import java.awt.geom.Line2D;
19 import java.awt.geom.Rectangle2D;
21 import org.simantics.scenegraph.g2d.G2DNode;
22 import org.simantics.scenegraph.utils.GeometryUtils;
24 public class RelationshipNode extends G2DNode {
26 private static final long serialVersionUID = 3517235896431855937L;
28 public static transient double PADDING = 1;
30 protected Stroke boxStroke = null;
31 protected Stroke lineStroke = null;
32 protected Color boxColor = null;
33 protected Color lineColor = null;
34 protected Shape bounds1 = null;
35 protected Shape bounds2 = null;
37 private transient Rectangle2D boundsInLocal = null;
38 private transient float phase = 0;
40 @SyncField({"boxstroke", "linestroke", "boxcolor", "linecolor", "bounds1", "bounds2"})
41 public void init(Stroke boxStroke, Stroke lineStroke, Color boxColor, Color lineColor, Shape bounds1, Shape bounds2) {
42 this.boxStroke = boxStroke;
43 this.lineStroke = lineStroke;
44 this.boxColor = boxColor;
45 this.lineColor = lineColor;
46 this.bounds1 = bounds1;
47 this.bounds2 = bounds2;
48 this.boundsInLocal = calculateLocalBounds();
52 public void render(Graphics2D g) {
53 if (bounds1 == null || bounds2 == null)
60 float scale = (float) (1.0 / GeometryUtils.getScale(g.getTransform()));
61 float scaledPhase = scale * phase;
63 Rectangle2D rect = bounds1.getBounds2D();
65 if (boxStroke != null && boxColor != null) {
66 g.setStroke(GeometryUtils.scaleAndOffsetStroke(boxStroke, scale, scaledPhase));
68 GeometryUtils.expandRectangle(rect, PADDING, PADDING, PADDING, PADDING);
72 if (lineStroke != null && lineColor != null) {
73 if (lineStroke != boxStroke)
74 g.setStroke(GeometryUtils.scaleAndOffsetStroke(lineStroke, scale, scaledPhase));
75 if (lineColor != boxColor)
76 g.setColor(lineColor);
77 Rectangle2D rect2 = bounds2.getBounds2D();
78 g.draw(new Line2D.Double(rect.getCenterX(), rect.getCenterY(), rect2.getCenterX(), rect2.getCenterY()));
83 public Rectangle2D getBoundsInLocal() {
87 private Rectangle2D calculateLocalBounds() {
88 if (bounds1 == null || bounds2 == null)
91 Rectangle2D rect = bounds1.getBounds2D();
92 Rectangle2D rect2 = bounds2.getBounds2D();
94 double x1 = rect.getCenterX();
95 double x2 = rect2.getCenterX();
96 double y1 = rect.getCenterY();
97 double y2 = rect2.getCenterY();
98 double minx = Math.min(x1, x2);
99 double maxx = Math.max(x1, x2);
100 double miny = Math.min(y1, y2);
101 double maxy = Math.max(y1, y2);
103 return new Rectangle2D.Double(minx, miny, maxx - minx, maxy - miny);