1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.scenegraph.g2d.nodes;
14 import java.awt.BasicStroke;
\r
15 import java.awt.Color;
\r
16 import java.awt.Graphics2D;
\r
17 import java.awt.Paint;
\r
18 import java.awt.Shape;
\r
19 import java.awt.Stroke;
\r
20 import java.awt.geom.AffineTransform;
\r
21 import java.awt.geom.Rectangle2D;
\r
23 import org.simantics.scenegraph.g2d.G2DNode;
\r
24 import org.simantics.scenegraph.utils.GeometryUtils;
\r
25 import org.simantics.scenegraph.utils.InitValueSupport;
\r
28 * A scene graph node that renders a specified AWT {@link Shape} by optionally
29 * filling or drawing it.
31 * If filling is enabled, it will be performed before stroking the shape.
34 * @author Tuukka Lehtonen
36 * TODO: separate paint for stroke and fill
38 public class ShapeNode extends G2DNode implements InitValueSupport {
40 private static final long serialVersionUID = 8508750881358776559L;
42 protected static final Stroke DEFAULT_STROKE = new BasicStroke(2);
\r
44 protected Shape shape = null;
\r
45 protected Stroke stroke = DEFAULT_STROKE;
46 protected Paint color = Color.BLACK;
47 protected boolean fill = false;
48 protected boolean scaleStroke = false;
49 protected boolean scaleShape = false;
51 protected transient Shape dynamicShape = null;
\r
52 protected transient Stroke dynamicStroke = null;
\r
53 protected transient Paint dynamicColor = null;
\r
54 protected transient Boolean dynamicFill = null;
\r
55 protected transient Boolean dynamicScaleStroke = null;
\r
56 protected transient Boolean dynamicScaleShape = null;
\r
58 @PropertySetter("shape")
60 public void setShape(Shape shape) {
65 @PropertySetter("stroke")
67 public void setStroke(Stroke stroke) {
71 @PropertySetter("color")
73 public void setColor(Paint color) {
78 public void setFill(boolean fill) {
82 @SyncField("scaleStroke")
83 public void setScaleStroke(boolean scaleStroke) {
84 this.scaleStroke = scaleStroke;
87 @SyncField("scaleShape")
88 public void setScaleShape(boolean scaleShape) {
89 this.scaleShape = scaleShape;
93 public void render(Graphics2D g2d) {
94 Shape shape = dynamicShape != null ? dynamicShape : this.shape;
\r
98 AffineTransform ot = setupRender(g2d);
\r
99 renderShape(g2d, shape);
\r
101 g2d.setTransform(ot);
106 * @return current transform
\r
108 protected AffineTransform setupRender(Graphics2D g2d) {
\r
109 AffineTransform old = null;
110 if (!transform.isIdentity()) {
\r
111 old = g2d.getTransform();
\r
112 g2d.transform(transform);
\r
115 Paint color = dynamicColor != null ? dynamicColor : this.color;
116 if (color != null) g2d.setPaint(color);
\r
118 Stroke stroke = dynamicStroke != null ? dynamicStroke : this.stroke;
119 if (stroke != null) {
\r
120 boolean scaleStroke = Boolean.TRUE.equals(dynamicScaleStroke) ? true : this.scaleStroke;
121 if (scaleStroke && stroke instanceof BasicStroke) {
122 BasicStroke bs = GeometryUtils.scaleStroke(stroke, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
125 g2d.setStroke(stroke);
129 boolean scaleShape = Boolean.TRUE.equals(dynamicScaleShape) ? true : this.scaleShape;
\r
131 double xs = g2d.getTransform().getScaleX();
132 double ys = g2d.getTransform().getScaleY();
133 g2d.scale(1/xs, 1/ys);
139 protected void renderShape(Graphics2D g2d, Shape s) {
\r
140 boolean fill = Boolean.TRUE.equals(dynamicFill) ? true : this.fill;
\r
144 Stroke stroke = dynamicStroke != null ? dynamicStroke : this.stroke;
\r
150 public Rectangle2D getBoundsInLocal() {
151 if(shape == null) return null;
152 return shape.getBounds2D();
155 public void setValue(String key, Object value) {
\r
156 if ("shape".equals(key))
\r
157 dynamicShape = (Shape) value;
\r
158 else if ("stroke".equals(key))
\r
159 dynamicStroke = (Stroke) value;
\r
160 else if ("color".equals(key))
\r
161 dynamicColor = (Paint) value;
\r
162 else if ("fill".equals(key))
\r
163 dynamicFill = (Boolean) value;
\r
164 else if ("scaleStroke".equals(key))
\r
165 dynamicScaleStroke = (Boolean) value;
\r
166 else if ("scaleShape".equals(key))
\r
167 dynamicScaleShape = (Boolean) value;
\r
168 // else super.setValue(key, value);
\r
172 public void initValues() {
\r
173 dynamicShape = null;
\r
174 dynamicStroke = null;
\r
175 dynamicColor = null;
\r
176 dynamicFill = null;
\r
177 dynamicScaleStroke = null;
\r
178 dynamicScaleShape = null;
\r
182 public String toString() {
\r
183 return super.toString() + " [shape=" + shape + ",color=" + color + "]";
\r