import java.awt.Color;\r
import java.awt.Graphics2D;\r
import java.awt.RenderingHints;\r
-import java.awt.Shape;\r
import java.awt.Stroke;\r
+import java.awt.geom.Path2D;\r
import java.awt.geom.Rectangle2D;\r
\r
import org.simantics.scenegraph.ISelectionPainterNode;\r
import org.simantics.scenegraph.g2d.G2DNode;\r
import org.simantics.scenegraph.utils.NodeUtil;\r
-import org.simantics.utils.datastructures.Pair;\r
\r
public class FlowNode extends G2DNode implements ISelectionPainterNode {\r
\r
private Rectangle2D beginBounds;\r
private Rectangle2D endBounds;\r
private Boolean toValve;\r
+ private transient Path2D lines;\r
+ private transient Path2D arrow;\r
\r
@PropertySetter("color")\r
@SyncField("color")\r
* -In the first case there is no arrow and valve is endBounds\r
* -In the second case there is an arrow and valve is beginBounds\r
*/\r
- \r
- Pair<Shape, Shape> lines = null;\r
- Shape arrow = null;\r
\r
// System.out.println("FlowNode.render toValve = " + toValve);\r
\r
if(toValve) {\r
- \r
- // FIXME: optimize memory allocations\r
- lines = Flows.createLines(false, endBounds, beginBounds);\r
-\r
+ lines = Flows.createLines(lines, false, endBounds, beginBounds);\r
} else {\r
-\r
- // FIXME: optimize memory allocations\r
- lines = Flows.createLines(true, beginBounds, endBounds);\r
- arrow = Flows.createArrow(beginBounds, endBounds);\r
- \r
+ lines = Flows.createLines(lines, true, beginBounds, endBounds);\r
+ arrow = Flows.createArrow(arrow, beginBounds, endBounds);\r
}\r
\r
boolean selected = NodeUtil.isSelected(this, 2);\r
if(selected) {\r
g.setColor(Color.PINK);\r
g.setStroke(STROKE);\r
- g.draw(lines.first);\r
- g.draw(lines.second);\r
+ g.draw(lines);\r
if(color != null) g.setColor(color);\r
g.setStroke(stroke);\r
- g.draw(lines.first);\r
- g.draw(lines.second);\r
+ g.draw(lines);\r
if(arrow != null) g.fill(arrow);\r
} else {\r
if(color != null) g.setColor(color);\r
if(stroke != null) g.setStroke(stroke);\r
- g.draw(lines.first);\r
- g.draw(lines.second);\r
+ g.draw(lines);\r
if(arrow != null) g.fill(arrow);\r
}\r
\r
*******************************************************************************/\r
package org.simantics.sysdyn.ui.elements2.connections;\r
\r
-import java.awt.Shape;\r
import java.awt.geom.Path2D;\r
import java.awt.geom.Rectangle2D;\r
\r
-import org.simantics.utils.datastructures.Pair;\r
-\r
public class Flows {\r
\r
public static double ARROW_LENGTH = 3.2;\r
static final double OFFSET = 1.0;\r
static final double ARROW_OFFSET = 3.2;\r
\r
- public static Path2D createArrow(Rectangle2D tail, Rectangle2D head) { \r
+ public static Path2D createArrow(Path2D arrow, Rectangle2D tail, Rectangle2D head) { \r
\r
double x = tail.getCenterX();\r
double y = tail.getCenterY();\r
\r
-// Rectangle2D rect = new Rectangle2D.Double();\r
-// head.getBounds(rect);\r
double cx = head.getCenterX();\r
double minx = head.getMinX();\r
double maxx = head.getMaxX();\r
double miny = head.getMinY();\r
double maxy = head.getMaxY();\r
\r
- Path2D path = new Path2D.Double();\r
+ arrow = new Path2D.Double();\r
\r
// approach from top\r
if (y < miny) {\r
- path.moveTo(cx, miny);\r
- path.lineTo(cx + ARROW_WIDTH, miny - ARROW_LENGTH);\r
- path.lineTo(cx - ARROW_WIDTH, miny - ARROW_LENGTH);\r
+ arrow.moveTo(cx, miny);\r
+ arrow.lineTo(cx + ARROW_WIDTH, miny - ARROW_LENGTH);\r
+ arrow.lineTo(cx - ARROW_WIDTH, miny - ARROW_LENGTH);\r
} \r
\r
// approach from beneath\r
else if (y > maxy) {\r
- path.moveTo(cx, maxy);\r
- path.lineTo(cx + ARROW_WIDTH, maxy + ARROW_LENGTH);\r
- path.lineTo(cx - ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+ arrow.moveTo(cx, maxy);\r
+ arrow.lineTo(cx + ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+ arrow.lineTo(cx - ARROW_WIDTH, maxy + ARROW_LENGTH);\r
}\r
\r
// approach from left\r
else if (x < minx) {\r
- path.moveTo(minx, y);\r
- path.lineTo(minx - ARROW_LENGTH, y - ARROW_WIDTH);\r
- path.lineTo(minx - ARROW_LENGTH, y + ARROW_WIDTH);\r
+ arrow.moveTo(minx, y);\r
+ arrow.lineTo(minx - ARROW_LENGTH, y - ARROW_WIDTH);\r
+ arrow.lineTo(minx - ARROW_LENGTH, y + ARROW_WIDTH);\r
}\r
\r
// approach from right\r
else if (x > maxx) {\r
- path.moveTo(maxx, y);\r
- path.lineTo(maxx + ARROW_LENGTH, y - ARROW_WIDTH);\r
- path.lineTo(maxx + ARROW_LENGTH, y + ARROW_WIDTH);\r
+ arrow.moveTo(maxx, y);\r
+ arrow.lineTo(maxx + ARROW_LENGTH, y - ARROW_WIDTH);\r
+ arrow.lineTo(maxx + ARROW_LENGTH, y + ARROW_WIDTH);\r
}\r
else\r
return null; // FIXME (HN) This is just a quick bugfix, didn't understand the logic completely \r
\r
- path.closePath();\r
+ arrow.closePath();\r
\r
- return path;\r
+ return arrow;\r
\r
}\r
\r
- private static Pair<Shape, Shape> createLines(boolean vertical, double ... coordinates) {\r
- \r
-// lineNode1.setShape(createOffsetLine(vertical, OFFSET, coordinates));\r
-// lineNode2.setShape(createOffsetLine(vertical, -OFFSET, coordinates));\r
- return new Pair<Shape, Shape>(createOffsetLine(vertical, OFFSET, coordinates), Flows.createOffsetLine(vertical, -OFFSET, coordinates));\r
- \r
+ private static Path2D createLines(Path2D lines, boolean vertical, double ... coordinates) {\r
+ lines = new Path2D.Double();\r
+ createOffsetLine(lines, vertical, OFFSET, coordinates);\r
+ createOffsetLine(lines, vertical, -OFFSET, coordinates);\r
+ return lines;\r
}\r
\r
- public static Pair<Shape, Shape> createLines(boolean hasArrow, Rectangle2D valve, Rectangle2D node) {\r
- \r
+ public static Path2D createLines(Path2D lines, boolean hasArrow, Rectangle2D valve, Rectangle2D node) {\r
double x0 = valve.getCenterX();\r
double y0 = valve.getCenterY(); \r
double x1 = node.getCenterX();\r
double y1 = node.getCenterY();\r
\r
-// System.out.println("FlowNode " + x0 + " " + y0 + " x1 " + x1 + " y1 " + y1);\r
-\r
-// Rectangle2D rect = new Rectangle2D.Double();\r
-// node.getBounds(rect);\r
- \r
double minY = hasArrow ? node.getMinY() - ARROW_OFFSET : node.getMinY();\r
double maxY = hasArrow ? node.getMaxY() + ARROW_OFFSET : node.getMaxY();\r
double minX = hasArrow ? node.getMinX() - ARROW_OFFSET : node.getMinX();\r
double maxX = hasArrow ? node.getMaxX() + ARROW_OFFSET : node.getMaxX();\r
\r
-// boolean rotated = ((ValveElement)valve).rotated;\r
boolean rotated = false;\r
\r
if( rotated ) {\r
y0 -= OFFSET;\r
if(node.getMinX() <= x0 && node.getMaxX() >= x0) {\r
if(y1 > y0)\r
- return createLines(true, y0, x0, minY);\r
+ return createLines(lines, true, y0, x0, minY);\r
else\r
- return createLines(true, y0, x0, maxY);\r
+ return createLines(lines, true, y0, x0, maxY);\r
}\r
else {\r
if(x1 > x0)\r
- return createLines(true, y0, x0, y1, minX);\r
+ return createLines(lines, true, y0, x0, y1, minX);\r
else\r
- return createLines(true, y0, x0, y1, maxX);\r
+ return createLines(lines, true, y0, x0, y1, maxX);\r
}\r
}\r
else {\r
x0 -= OFFSET;\r
if(node.getMinY() <= y0 && node.getMaxY() >= y0) {\r
if(x1 > x0)\r
- return createLines(false, x0, y0, minX);\r
+ return createLines(lines, false, x0, y0, minX);\r
else\r
- return createLines(false, x0, y0, maxX);\r
+ return createLines(lines, false, x0, y0, maxX);\r
}\r
else {\r
if(y1 > y0)\r
- return createLines(false, x0, y0, x1, minY);\r
+ return createLines(lines, false, x0, y0, x1, minY);\r
else\r
- return createLines(false, x0, y0, x1, maxY);\r
+ return createLines(lines, false, x0, y0, x1, maxY);\r
}\r
}\r
\r
\r
}\r
\r
- public static Path2D createLine(boolean vertical, double ... coordinates) {\r
- Path2D path = new Path2D.Double();\r
+ public static Path2D createLine(Path2D path, boolean vertical, double ... coordinates) {\r
if(vertical)\r
path.moveTo(coordinates[1], coordinates[0]);\r
else\r
return path;\r
}\r
\r
- public static Path2D createOffsetLine(boolean vertical, double offset, double ... coordinates) {\r
+ public static Path2D createOffsetLine(Path2D path, boolean vertical, double offset, double ... coordinates) {\r
double[] newCoordinats = new double[coordinates.length];\r
newCoordinats[0] = coordinates[0];\r
newCoordinats[coordinates.length-1] = coordinates[coordinates.length-1];\r
else\r
newCoordinats[i] = coordinates[i]-offset;\r
}\r
- return createLine(vertical, newCoordinats);\r
+ return createLine(path, vertical, newCoordinats);\r
}\r
\r
}\r