diff --git a/jdk16-examples/pom.xml b/jdk16-examples/pom.xml new file mode 100644 index 0000000..5f7bdc9 --- /dev/null +++ b/jdk16-examples/pom.xml @@ -0,0 +1,83 @@ + + + + 4.0.0 + + piccolo2d-parent + org.piccolo2d + 2.0-SNAPSHOT + ../parent/pom.xml + + piccolo2d-examples + Piccolo2D JDK16 Examples + bundle + + 1.6 + + + + org.piccolo2d + piccolo2d-extras + ${project.version} + + + org.piccolo2d + piccolo2d-jdk16 + ${project.version} + + + + scm:svn:http://piccolo2d.googlecode.com/svn/piccolo2d.java/trunk/jdk16-examples + scm:svn:https://piccolo2d.googlecode.com/svn/piccolo2d.java/trunk/jdk16-examples + http://code.google.com/p/piccolo2d/source/browse/piccolo2d.java/trunk/jdk16-examples + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + jar-with-dependencies + + + + + + diff --git a/jdk16-examples/src/main/java/org/piccolo2d/jdk16/examples/AreaExample.java b/jdk16-examples/src/main/java/org/piccolo2d/jdk16/examples/AreaExample.java new file mode 100644 index 0000000..ba87377 --- /dev/null +++ b/jdk16-examples/src/main/java/org/piccolo2d/jdk16/examples/AreaExample.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.examples; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Paint; +import java.awt.Stroke; + +import java.awt.geom.Area; + +import org.piccolo2d.PCanvas; + +import org.piccolo2d.event.PBasicInputEventHandler; +import org.piccolo2d.event.PInputEvent; +import org.piccolo2d.event.PInputEventListener; + +import org.piccolo2d.extras.PFrame; + +import org.piccolo2d.jdk16.nodes.PArea; +import org.piccolo2d.jdk16.nodes.PPath; + +import org.piccolo2d.util.PBounds; + +/** + * Area example. + */ +public final class AreaExample extends PFrame { + + /** Default serial version UID. */ + private static final long serialVersionUID = 1L; + + /** Path paint. */ + private static final Paint PAINT = new Color(20, 20, 20, 120); + + /** Area paint. */ + private static final Paint AREA_PAINT = new Color(0, 0, 0, 0); + + /** Stroke. */ + private static final Stroke STROKE = new BasicStroke(0.5f); + + /** Area stroke. */ + private static final Stroke AREA_STROKE = null; + + /** Stroke paint. */ + private static final Paint STROKE_PAINT = new Color(20, 20, 20, 200); + + /** Mouseover paint. */ + private static final Paint MOUSEOVER_PAINT = new Color(10, 10, 10); + + + /** + * Create a new area example. + */ + public AreaExample() { + this(null); + } + + /** + * Create a new area example with the specified canvas. + * + * @param canvas canvas for this area example + */ + public AreaExample(final PCanvas canvas) { + super("AreaExample", false, canvas); + } + + + /** {@inheritDoc} */ + public void initialize() { + + /* + Example based on TertiaryVennNode.java, see + http://www.dishevelled.org/piccolo-venn + */ + + PPath first = PPath.createEllipse(0.0d, 0.0d, 128.0d, 128.0d); + PPath second = PPath.createEllipse((2.0d * 128.0d) / 3.0d, 0.0d, 128.0d, 128.0d); + PPath third = PPath.createEllipse(128.0d / 3.0d, (2.0d * 128.0d) / 3.0d, 128.0d, 128.0d); + + first.setStroke(STROKE); + second.setStroke(STROKE); + third.setStroke(STROKE); + + Area f = new Area(first.getPathReference()); + Area s = new Area(second.getPathReference()); + Area t = new Area(third.getPathReference()); + + PArea firstOnly = new PArea(AREA_STROKE); + firstOnly.add(f); + firstOnly.subtract(s); + firstOnly.subtract(t); + + PArea secondOnly = new PArea(AREA_STROKE); + secondOnly.add(s); + secondOnly.subtract(f); + secondOnly.subtract(t); + + PArea thirdOnly = new PArea(AREA_STROKE); + thirdOnly.add(t); + thirdOnly.subtract(f); + thirdOnly.subtract(s); + + PArea firstSecond = new PArea(AREA_STROKE); + firstSecond.add(f); + firstSecond.intersect(s); + firstSecond.subtract(t); + + PArea firstThird = new PArea(AREA_STROKE); + firstThird.add(f); + firstThird.intersect(t); + firstThird.subtract(s); + + PArea secondThird = new PArea(AREA_STROKE); + secondThird.add(s); + secondThird.intersect(t); + secondThird.subtract(f); + + PArea intersection = new PArea(AREA_STROKE); + intersection.add(f); + intersection.intersect(s); + intersection.intersect(t); + + PInputEventListener mouseOver = new PBasicInputEventHandler() { + + /** {@inheritDoc} */ + public void mouseEntered(final PInputEvent event) { + event.getPickedNode().setPaint(MOUSEOVER_PAINT); + } + + /** {@inheritDoc} */ + public void mouseExited(final PInputEvent event) { + event.getPickedNode().setPaint(PAINT); + } + }; + + firstOnly.addInputEventListener(mouseOver); + secondOnly.addInputEventListener(mouseOver); + thirdOnly.addInputEventListener(mouseOver); + firstSecond.addInputEventListener(mouseOver); + firstThird.addInputEventListener(mouseOver); + secondThird.addInputEventListener(mouseOver); + intersection.addInputEventListener(mouseOver); + + first.setPaint(PAINT); + first.setStrokePaint(STROKE_PAINT); + second.setPaint(PAINT); + second.setStrokePaint(STROKE_PAINT); + third.setPaint(PAINT); + third.setStrokePaint(STROKE_PAINT); + firstOnly.setPaint(AREA_PAINT); + secondOnly.setPaint(AREA_PAINT); + thirdOnly.setPaint(AREA_PAINT); + firstSecond.setPaint(AREA_PAINT); + firstThird.setPaint(AREA_PAINT); + secondThird.setPaint(AREA_PAINT); + intersection.setPaint(AREA_PAINT); + + getCanvas().getLayer().addChild(first); + getCanvas().getLayer().addChild(second); + getCanvas().getLayer().addChild(third); + getCanvas().getLayer().addChild(firstOnly); + getCanvas().getLayer().addChild(secondOnly); + getCanvas().getLayer().addChild(thirdOnly); + getCanvas().getLayer().addChild(firstSecond); + getCanvas().getLayer().addChild(firstThird); + getCanvas().getLayer().addChild(secondThird); + getCanvas().getLayer().addChild(intersection); + + PBounds center = getCanvas().getLayer().getFullBoundsReference(); + getCanvas().getCamera().animateViewToCenterBounds(center, false, 0L); + } + + + /** + * Main. + * + * @param args command line arguments, ignored + */ + public static void main(final String[] args) { + new AreaExample(); + } +} \ No newline at end of file diff --git a/jdk16-examples/src/main/java/org/piccolo2d/jdk16/examples/PathExample.java b/jdk16-examples/src/main/java/org/piccolo2d/jdk16/examples/PathExample.java new file mode 100644 index 0000000..f0fb500 --- /dev/null +++ b/jdk16-examples/src/main/java/org/piccolo2d/jdk16/examples/PathExample.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.examples; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Paint; +import java.awt.Stroke; + +import java.awt.geom.Arc2D; + +import org.piccolo2d.PCanvas; + +import org.piccolo2d.event.PBasicInputEventHandler; +import org.piccolo2d.event.PInputEvent; +import org.piccolo2d.event.PInputEventListener; + +import org.piccolo2d.extras.PFrame; + +import org.piccolo2d.jdk16.nodes.PPath; + +/** + * Path example. + */ +public final class PathExample extends PFrame { + + /** Default serial version UID. */ + private static final long serialVersionUID = 1L; + + /** Path paint. */ + private static final Paint PAINT = new Color(20, 20, 20, 120); + + /** Stroke. */ + private static final Stroke STROKE = new BasicStroke(0.5f); + + /** Stroke paint. */ + private static final Paint STROKE_PAINT = new Color(20, 20, 20, 120); + + /** Mouseover paint. */ + private static final Paint MOUSEOVER_PAINT = new Color(252, 233, 79); + + /** Mouseover stroke paint. */ + private static final Paint MOUSEOVER_STROKE_PAINT = new Color(237, 212, 0); + + + /** + * Create a new path example. + */ + public PathExample() { + this(null); + } + + /** + * Create a new path example with the specified canvas. + * + * @param canvas canvas for this path example + */ + public PathExample(final PCanvas canvas) { + super("PathExample", false, canvas); + } + + + /** {@inheritDoc} */ + public void initialize() { + + PPath arc = PPath.createArc(-75.0d, 25.0d, 200.0d, 200.0d, 30.0d, 60.0d, Arc2D.PIE); + PPath cubicCurve = PPath.createCubicCurve(100.0d, 100.0d, 150.0d, 125.0d, 175.0d, 150.0d, 200.0d, 200.0d); + PPath ellipse = PPath.createEllipse(250.0d, 250.0d, 90.0d, 90.0d); + PPath line = PPath.createLine(10.0d, 390.0d, 200.0d, 200.0d); + PPath quadCurve = PPath.createQuadCurve(390.0d, 10.0d, 375.0d, 80.0d, 200.0d, 200.0d); + PPath rectangle = PPath.createRectangle(180.0d, 300.0d, 40.0d, 60.0d); + PPath roundRectangle = PPath.createRoundRectangle(280.0d, 180.0d, 60.0d, 40.0d, 4.0d, 8.0d); + + arc.setPaint(PAINT); + arc.setStroke(STROKE); + arc.setStrokePaint(STROKE_PAINT); + cubicCurve.setPaint(PAINT); + cubicCurve.setStroke(STROKE); + cubicCurve.setStrokePaint(STROKE_PAINT); + ellipse.setPaint(PAINT); + ellipse.setStroke(STROKE); + ellipse.setStrokePaint(STROKE_PAINT); + line.setPaint(PAINT); + line.setStroke(STROKE); + line.setStrokePaint(STROKE_PAINT); + quadCurve.setPaint(PAINT); + quadCurve.setStroke(STROKE); + quadCurve.setStrokePaint(STROKE_PAINT); + rectangle.setPaint(PAINT); + rectangle.setStroke(STROKE); + rectangle.setStrokePaint(STROKE_PAINT); + roundRectangle.setPaint(PAINT); + roundRectangle.setStroke(STROKE); + roundRectangle.setStrokePaint(STROKE_PAINT); + + PInputEventListener mouseOver = new PBasicInputEventHandler() { + + /** {@inheritDoc} */ + public void mouseEntered(final PInputEvent event) { + event.getPickedNode().setPaint(MOUSEOVER_PAINT); + ((PPath) event.getPickedNode()).setStrokePaint(MOUSEOVER_STROKE_PAINT); + } + + /** {@inheritDoc} */ + public void mouseExited(final PInputEvent event) { + event.getPickedNode().setPaint(PAINT); + ((PPath) event.getPickedNode()).setStrokePaint(STROKE_PAINT); + } + }; + + arc.addInputEventListener(mouseOver); + cubicCurve.addInputEventListener(mouseOver); + ellipse.addInputEventListener(mouseOver); + line.addInputEventListener(mouseOver); + quadCurve.addInputEventListener(mouseOver); + rectangle.addInputEventListener(mouseOver); + roundRectangle.addInputEventListener(mouseOver); + + getCanvas().getLayer().addChild(arc); + getCanvas().getLayer().addChild(cubicCurve); + getCanvas().getLayer().addChild(ellipse); + getCanvas().getLayer().addChild(line); + getCanvas().getLayer().addChild(quadCurve); + getCanvas().getLayer().addChild(rectangle); + getCanvas().getLayer().addChild(roundRectangle); + } + + + /** + * Main. + * + * @param args command line arguments, ignored + */ + public static void main(final String[] args) { + new PathExample(); + } +} \ No newline at end of file diff --git a/jdk16-examples/src/main/java/org/piccolo2d/jdk16/examples/package-info.java b/jdk16-examples/src/main/java/org/piccolo2d/jdk16/examples/package-info.java new file mode 100644 index 0000000..965c407 --- /dev/null +++ b/jdk16-examples/src/main/java/org/piccolo2d/jdk16/examples/package-info.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Examples for Piccolo2D classes that require a minimum JDK version of 1.6. + */ +package org.piccolo2d.jdk16.examples; \ No newline at end of file diff --git a/jdk16/pom.xml b/jdk16/pom.xml new file mode 100644 index 0000000..a501cd1 --- /dev/null +++ b/jdk16/pom.xml @@ -0,0 +1,167 @@ + + + + 4.0.0 + + piccolo2d-parent + org.piccolo2d + 2.0-SNAPSHOT + ../parent/pom.xml + + piccolo2d-jdk16 + bundle + Piccolo2D JDK16 + + 1.6 + + + + org.piccolo2d + piccolo2d-core + ${project.version} + + + + scm:svn:http://piccolo2d.googlecode.com/svn/piccolo2d.java/trunk/jdk16 + scm:svn:https://piccolo2d.googlecode.com/svn/piccolo2d.java/trunk/jdk16 + http://code.google.com/p/piccolo2d/source/browse/piccolo2d.java/trunk/jdk16 + + + + + maven-checkstyle-plugin + 2.3 + + ${basedir}/src/build/conf/checkstyle.xml + false + + + + maven-javadoc-plugin + 2.6.1 + + ${jdk.version} + false + package + + + + + javadoc + + + + + + maven-surefire-report-plugin + 2.4.3 + + + maven-changelog-plugin + 2.1 + + + + maven-jxr-plugin + 2.1 + + + org.codehaus.mojo + taglist-maven-plugin + 2.4 + + + TODO + FIXME + @todo + @deprecated + + + + + maven-project-info-reports-plugin + 2.1.2 + + + maven-pmd-plugin + 2.4 + + ascii + ${jdk.version} + + + + org.codehaus.mojo + jdepend-maven-plugin + 2.0-beta-2 + + + org.codehaus.mojo + findbugs-maven-plugin + 2.1 + + + true + true + true + target/site + false + + + + org.codehaus.mojo + cobertura-maven-plugin + 2.3 + + + xml + html + + + + org.piccolo2d.examples.* + org.piccolo2d.examples.pswing.* + org.piccolo2d.examples.swt.* + org.piccolo2d.tutorial.* + + + org/piccolo2d/examples/** + + + + + + + diff --git a/jdk16/src/build/conf/checkstyle.xml b/jdk16/src/build/conf/checkstyle.xml new file mode 100644 index 0000000..dba0289 --- /dev/null +++ b/jdk16/src/build/conf/checkstyle.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/PArea.java b/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/PArea.java new file mode 100644 index 0000000..8e541ad --- /dev/null +++ b/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/PArea.java @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.nodes; + +import java.awt.Shape; +import java.awt.Stroke; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Area; + +/** + * Area node. + */ +public final class PArea extends PShape { + + /** Area for this area node. */ + private final transient Area area; + + + /** + * Create a new area node with an empty area. + */ + public PArea() { + area = new Area(); + } + + /** + * Create a new area node with an empty area and the specified stroke. + * + * @param stroke stroke + */ + public PArea(final Stroke stroke) { + area = new Area(); + setStroke(stroke); + } + + /** + * Create a new area node with the specified shape. + * + * @param shape shape, must not be null + */ + public PArea(final Shape shape) { + if (shape == null) { + throw new NullPointerException("shape must not be null"); + } + this.area = new Area(shape); + } + + /** + * Create a new area node with the specified shape and stroke. + * + * @param shape shape, must not be null + * @param stroke stroke + */ + public PArea(final Shape shape, final Stroke stroke) { + if (shape == null) { + throw new NullPointerException("shape must not be null"); + } + this.area = new Area(shape); + setStroke(stroke); + } + + /** + * Create a new area node with the specified area. + * + * @param area area, must not be null + */ + public PArea(final Area area) { + if (area == null) { + throw new NullPointerException("area must not be null"); + } + this.area = new Area(); + this.area.add(area); + } + + /** + * Create a new area node with the specified area and stroke. + * + * @param area area, must not be null + * @param stroke stroke + */ + public PArea(final Area area, final Stroke stroke) { + if (area == null) { + throw new NullPointerException("area must not be null"); + } + this.area = new Area(); + this.area.add(area); + setStroke(stroke); + } + + + /** + * Return a copy of the area backing this area node. + * + * @return a copy of the area backing this area node + */ + public Area getArea() { + return (Area) area.clone(); + } + + /** + * Return the area backing this node. The returned area must not be + * modified or the bounds of this node may no longer be valid and any + * area property change listeners will not be notified. + * + * @return the area backing this area node + */ + public Area getAreaReference() { + return area; + } + + /** + * Add the shape of the specified area to the shape of this area node. + * The resulting shape of this area node will include the union of both shapes, + * or all areas that were contained in either this or the specified area. + * + * @param area area to add, must not be null + * @throws NullPointerException if area is null + */ + public void add(final Area area) { + Area oldArea = (Area) this.area.clone(); + this.area.add(area); + updateBoundsFromShape(); + firePropertyChange(-1, "area", oldArea, getArea()); + } + + /** + * Set the shape of this area node to be the combined area of its current + * shape and the shape of the specified area, minus their intersection. The + * resulting shape of this area node will include only areas that were contained + * in either this area node or in the specified area, but not in both. + * + * @param area area to exclusive or, must not be null + * @throws NullPointerException if area is null + */ + public void exclusiveOr(final Area area) { + Area oldArea = (Area) this.area.clone(); + this.area.exclusiveOr(area); + updateBoundsFromShape(); + firePropertyChange(-1, "area", oldArea, getArea()); + } + + /** + * Set the shape of this area node to the intersection of its current shape + * and the shape of the specified area. The resulting shape of this area node + * will include only areas that were contained in both this area node and also + * in the specified area. + * + * @param area area to intersect, must not be null + * @throws NullPointerException if area is null + */ + public void intersect(final Area area) { + Area oldArea = (Area) this.area.clone(); + this.area.intersect(area); + updateBoundsFromShape(); + firePropertyChange(-1, "area", oldArea, getArea()); + } + + /** + * Subtract the shape of the specified area from the shape of this area node. + * The resulting shape of this area node will include areas that were contained + * only in this area node and not in the specified area. + * + * @param area area to subtract, must not be null + * @throws NullPointerException if area is null + */ + public void subtract(final Area area) { + Area oldArea = (Area) this.area.clone(); + this.area.subtract(area); + updateBoundsFromShape(); + firePropertyChange(-1, "area", oldArea, getArea()); + } + + /** + * Removes all of the geometry from this area node and restores it to an empty area. + */ + public void reset() { + Area oldArea = (Area) area.clone(); + area.reset(); + updateBoundsFromShape(); + firePropertyChange(-1, "area", oldArea, getArea()); + } + + /** + * Return true if this area node represents an empty area. + * + * @return true if this area node represents an empty area + */ + public boolean isEmpty() { + return area.isEmpty(); + } + + /** + * Return true if this area node consists entirely of straight-edged polygonal geometry. + * + * @return true if this area node consists entirely of straight-edged polygonal geometry + */ + public boolean isPolygonal() { + return area.isPolygonal(); + } + + /** + * Return true if this area node is rectangular in shape. + * + * @return true if this area node is rectangular in shape + */ + public boolean isRectangular() { + return area.isRectangular(); + } + + /** + * Return true if this area node is comprised of a single closed subpath. This + * method returns true if the path contains 0 or 1 subpaths, or false if the path + * contains more than 1 subpath. The subpaths are counted by the number of + * SEG_MOVETO segments that appear in the path. + * + * @return true if this area node is comprised of a single closed subpath + */ + public boolean isSingular() { + return area.isSingular(); + } + + // todo: + // should modifiers return this to allow chaining, e.g. add(area0).intersect(area1) + // test serialization, may have to add custom code to serialize areas + + /** {@inheritDoc} */ + protected Shape getShape() { + return area; + } + + /** {@inheritDoc} */ + protected void transform(final AffineTransform transform) { + area.transform(transform); + } +} \ No newline at end of file diff --git a/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/PPath.java b/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/PPath.java new file mode 100644 index 0000000..9a9ef4a --- /dev/null +++ b/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/PPath.java @@ -0,0 +1,661 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.nodes; + +import java.awt.Shape; +import java.awt.Stroke; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.CubicCurve2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; +import java.awt.geom.Path2D; +import java.awt.geom.QuadCurve2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.awt.geom.PathIterator; + +/** + * Abstract path node. + */ +public abstract class PPath extends PShape { + + /** Path for this path node. */ + private final Path2D path; + + + /** + * Create a new path node with the specified path. + * + * @param path path + */ + private PPath(final Path2D path) { + this.path = (Path2D) path.clone(); + updateBoundsFromShape(); + } + + /** + * Create a new path node with the specified path and stroke. + * + * @param path path + * @param stroke stroke + */ + private PPath(final Path2D path, final Stroke stroke) { + this.path = (Path2D) path.clone(); + setStroke(stroke); + } + + + /** + * Path node with coordinates stored in single precision floating point. + */ + public static final class Float extends PPath { + + /** + * Create a new empty path node. + */ + public Float() { + super(new Path2D.Float()); + } + + /** + * Create a new empty path node with the specified stroke. + * + * @param stroke stroke + */ + public Float(final Stroke stroke) { + super(new Path2D.Float(), stroke); + } + + /** + * Create a new path node with the specified shape. + * + * @param shape shape, must not be null + * @throws NullPointerException if shape is null + */ + public Float(final Shape shape) { + super(new Path2D.Float(shape)); + } + + /** + * Create a new path node with the specified shape and stroke. + * + * @param shape shape, must not be null + * @param stroke stroke + * @throws NullPointerException if shape is null + */ + public Float(final Shape shape, final Stroke stroke) { + super(new Path2D.Float(shape), stroke); + } + + /** + * Create a new path node with the specified path. + * + * @param path path, must not be null + * @throws NullPointerException if path is null + */ + public Float(final Path2D.Float path) { + super(path); + } + + /** + * Create a new path node with the specified path and stroke. + * + * @param path path, must not be null + * @param stroke stroke, must not be null + * @throws NullPointerException if path is null + */ + public Float(final Path2D.Float path, final Stroke stroke) { + super(path, stroke); + } + } + + /** + * Path node with coordinates stored in double precision floating point. + */ + public static final class Double extends PPath { + + /** + * Create a new empty path node. + */ + public Double() { + super(new Path2D.Double()); + } + + /** + * Create a new empty path node with the specified stroke. + * + * @param stroke stroke + */ + public Double(final Stroke stroke) { + super(new Path2D.Double(), stroke); + } + + /** + * Create a new path node with the specified shape. + * + * @param shape shape, must not be null + * @throws NullPointerException if shape is null + */ + public Double(final Shape shape) { + super(new Path2D.Double(shape)); + } + + /** + * Create a new path node with the specified shape and stroke. + * + * @param shape shape, must not be null + * @param stroke stroke + * @throws NullPointerException if shape is null + */ + public Double(final Shape shape, final Stroke stroke) { + super(new Path2D.Double(shape), stroke); + } + + /** + * Create a new path node with the specified path. + * + * @param path path, must not be null + * @throws NullPointerException if path is null + */ + public Double(final Path2D.Double path) { + super(path); + } + + /** + * Create a new path node with the specified path and stroke. + * + * @param path path, must not be null + * @param stroke stroke + * @throws NullPointerException if path is null + */ + public Double(final Path2D.Double path, final Stroke stroke) { + super(path, stroke); + } + } + + + /** + * Create and return a new path node with the specified arc in single + * precision floating point coordinates. + * + * @param x x coordinate of the upper-left corner of the arc's framing rectangle + * @param y y coordinate of the upper-left corner of the arc's framing rectangle + * @param width width of the full ellipse of which this arc is a partial section + * @param height height of the full ellipse of which this arc is a partial section + * @param start starting angle of the arc in degrees + * @param extent angular extent of the arc in degrees + * @param type closure type for the arc, one of {@link Arc2D#OPEN}, {@link Arc2D#CHORD}, + * or {@link Arc2D#PIE} + * @return a new path node with the specified arc in single + * precision floating point coordinates + */ + public static final PPath createArc(final float x, + final float y, + final float width, + final float height, + final float start, + final float extent, + final int type) { + return new PPath.Float(new Arc2D.Float(x, y, width, height, start, extent, type)); + } + + /** + * Create and return a new path node with the specified cubic curve in single + * precision floating point coordinates. + * + * @param x1 x coordinate of the start point + * @param y1 y coordinate of the start point + * @param ctrlx1 x coordinate of the first control point + * @param ctrly1 y coordinate of the first control point + * @param ctrlx2 x coordinate of the second control point + * @param ctrly2 y coordinate of the second control point + * @param x2 x coordinate of the end point + * @param y2 y coordinate of the end point + * @return a new path node with the specified cubic curve in single + * precision floating point coordinates + */ + public static final PPath createCubicCurve(final float x1, + final float y1, + final float ctrlx1, + final float ctrly1, + final float ctrlx2, + final float ctrly2, + final float x2, + final float y2) { + return new PPath.Float(new CubicCurve2D.Float(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2)); + } + + /** + * Create and return a new path node with the specified ellipse in single + * precision floating point coordinates. + * + * @param x x coordinate + * @param y y coordinate + * @param width width + * @param height height + * @return a new path node with the specified ellipse in single + * precision floating point coordinates + */ + public static final PPath createEllipse(final float x, final float y, final float width, final float height) { + return new PPath.Float(new Ellipse2D.Float(x, y, width, height)); + } + + /** + * Create and return a new path node with the specified line in single + * precision floating point coordinates. + * + * @param x1 x coordinate of the start point + * @param y1 y coordinate of the start point + * @param x2 x coordinate of the end point + * @param y2 y coordinate of the end point + * @return a new path node with the specified line in single + * precision floating point coordinates + */ + public static final PPath createLine(final float x1, final float y1, final float x2, final float y2) { + return new PPath.Float(new Line2D.Float(x1, y1, x2, y2)); + } + + /* + need setPathToPolyline + public static final PPath createPolyline(final float[] xp, final float[] yp) { + } + + public static final PPath createPolyline(final Point2D.Float[] points) { + } + */ + + /** + * Create and return a new path node with the specified quadratic curve in single + * precision floating point coordinates. + * + * @param x1 x coordinate of the start point + * @param y1 y coordinate of the start point + * @param ctrlx x coordinate of the control point + * @param ctrly y coordinate of the control point + * @param x2 x coordinate of the end point + * @param y2 y coordinate of the end point + * @return a new path node with the specified quadratic curve in single + * precision floating point coordinates + */ + public static final PPath createQuadCurve(final float x1, + final float y1, + final float ctrlx, + final float ctrly, + final float x2, + final float y2) { + return new PPath.Float(new QuadCurve2D.Float(x1, y1, ctrlx, ctrly, x2, y2)); + } + + /** + * Create and return a new path node with the specified rectangle in single + * precision floating point coordinates. + * + * @param x x coordinate + * @param y y coordinate + * @param width width + * @param height height + * @return a new path node with the specified rectangle in single + * precision floating point coordinates + */ + public static final PPath createRectangle(final float x, final float y, final float width, final float height) { + return new PPath.Float(new Rectangle2D.Float(x, y, width, height)); + } + + /** + * Create and return a new path node with the specified round rectangle in single + * precision floating point coordinates. + * + * @param x x coordinate + * @param y y coordinate + * @param width width + * @param height height + * @param arcWidth width of the arc that rounds off the corners + * @param arcHeight height of the arc that rounds off the corners + * @return a new path node with the specified round rectangle in single + * precision floating point coordinates + */ + public static final PPath createRoundRectangle(final float x, + final float y, + final float width, + final float height, + final float arcWidth, + final float arcHeight) { + return new PPath.Float(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight)); + } + + /** + * Create and return a new path node with the specified arc in double + * precision floating point coordinates. + * + * @param x x coordinate of the upper-left corner of the arc's framing rectangle + * @param y y coordinate of the upper-left corner of the arc's framing rectangle + * @param width width of the full ellipse of which this arc is a partial section + * @param height height of the full ellipse of which this arc is a partial section + * @param start starting angle of the arc in degrees + * @param extent angular extent of the arc in degrees + * @param type closure type for the arc, one of {@link Arc2D#OPEN}, {@link Arc2D#CHORD}, + * or {@link Arc2D#PIE} + * @return a new path node with the specified arc in double + * precision floating point coordinates + */ + public static final PPath createArc(final double x, + final double y, + final double width, + final double height, + final double start, + final double extent, + final int type) { + return new PPath.Double(new Arc2D.Double(x, y, width, height, start, extent, type)); + } + + /** + * Create and return a new path node with the specified cubic curve in double + * precision floating point coordinates. + * + * @param x1 x coordinate of the start point + * @param y1 y coordinate of the start point + * @param ctrlx1 x coordinate of the first control point + * @param ctrly1 y coordinate of the first control point + * @param ctrlx2 x coordinate of the second control point + * @param ctrly2 y coordinate of the second control point + * @param x2 x coordinate of the end point + * @param y2 y coordinate of the end point + * @return a new path node with the specified cubic curve in double + * precision floating point coordinates + */ + public static final PPath createCubicCurve(final double x1, + final double y1, + final double ctrlx1, + final double ctrly1, + final double ctrlx2, + final double ctrly2, + final double x2, + final double y2) { + return new PPath.Double(new CubicCurve2D.Double(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2)); + } + + /** + * Create and return a new path node with the specified ellipse in double + * precision floating point coordinates. + * + * @param x x coordinate + * @param y y coordinate + * @param width width + * @param height height + * @return a new path node with the specified ellipse in double + * precision floating point coordinates + */ + public static final PPath createEllipse(final double x, final double y, final double width, final double height) { + return new PPath.Double(new Ellipse2D.Double(x, y, width, height)); + } + + /** + * Create and return a new path node with the specified line in double + * precision floating point coordinates. + * + * @param x1 x coordinate of the start point + * @param y1 y coordinate of the start point + * @param x2 x coordinate of the end point + * @param y2 y coordinate of the end point + * @return a new path node with the specified line in double + * precision floating point coordinates + */ + public static final PPath createLine(final double x1, final double y1, final double x2, final double y2) { + return new PPath.Double(new Line2D.Double(x1, y1, x2, y2)); + } + + /* + public static final PPath createPolyline(final double[] xp, final double[] yp) { + } + + public static final PPath createPolyline(final Point2D.Double[] points) { + } + */ + + /** + * Create and return a new path node with the specified quadratic curve in double + * precision floating point coordinates. + * + * @param x1 x coordinate of the start point + * @param y1 y coordinate of the start point + * @param ctrlx x coordinate of the control point + * @param ctrly y coordinate of the control point + * @param x2 x coordinate of the end point + * @param y2 y coordinate of the end point + * @return a new path node with the specified quadratic curve in double + * precision floating point coordinates + */ + public static final PPath createQuadCurve(final double x1, + final double y1, + final double ctrlx, + final double ctrly, + final double x2, + final double y2) { + return new PPath.Double(new QuadCurve2D.Double(x1, y1, ctrlx, ctrly, x2, y2)); + } + + /** + * Create and return a new path node with the specified rectangle in double + * precision floating point coordinates. + * + * @param x x coordinate + * @param y y coordinate + * @param width width + * @param height height + * @return a new path node with the specified rectangle in double + * precision floating point coordinates + */ + public static final PPath createRectangle(final double x, final double y, final double width, final double height) { + return new PPath.Double(new Rectangle2D.Double(x, y, width, height)); + } + + /** + * Create and return a new path node with the specified round rectangle in double + * precision floating point coordinates. + * + * @param x x coordinate + * @param y y coordinate + * @param width width + * @param height height + * @param arcWidth width of the arc that rounds off the corners + * @param arcHeight height of the arc that rounds off the corners + * @return a new path node with the specified round rectangle in double + * precision floating point coordinates + */ + public static final PPath createRoundRectangle(final double x, + final double y, + final double width, + final double height, + final double arcWidth, + final double arcHeight) { + return new PPath.Double(new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight)); + } + + + /** + * Return a copy of the path backing this path node. + * + * @return a copy of the path backing this path node + */ + public final Path2D getPath() { + return (Path2D) path.clone(); + } + + /** + * Return the path backing this node. The returned path must not be + * modified or the bounds of this node may no longer be valid and any + * path property change listeners will not be notified. + * + * @return the path backing this path node + */ + public final Path2D getPathReference() { + return path; + } + + /** + * Append the geometry of the specified shape to this path node, possibly + * connecting the new geometry to the existing path segments with a line + * segment. If the connect parameter is true and the path is not empty then + * any initial moveTo in the geometry of the appended shape is turned into + * a lineTo segment. If the destination coordinates of such a connecting + * lineTo segment match the ending coordinates of a currently open subpath + * then the segment is omitted as superfluous. The winding rule of the specified + * shape is ignored and the appended geometry is governed by the winding + * rule specified for this path node. + * + * @param shape shape to append to this path node + * @param connect true to turn an initial moveTo segment into a + * lineTo segment to connect the new geometry to the existing path + */ + public final void append(final Shape shape, final boolean connect) { + Path2D oldPath = (Path2D) path.clone(); + path.append(shape, connect); + updateBoundsFromShape(); + firePropertyChange(-1, "path", oldPath, getPath()); + } + + /** + * Append the geometry of the specified path iterator to this path node, possibly + * connecting the new geometry to the existing path segments with a line segment. + * If the connect parameter is true and the path is not empty then any initial moveTo + * in the geometry of the appended path iterator is turned into a lineTo segment. + * If the destination coordinates of such a connecting lineTo segment match + * the ending coordinates of a currently open subpath then the segment is omitted + * as superfluous. + * + * @param pathIterator path iterator to append to this path node + * @param connect true to turn an initial moveTo segment into a + * lineTo segment to connect the new geometry to the existing path + */ + public final void append(final PathIterator pathIterator, final boolean connect) { + Path2D oldPath = (Path2D) path.clone(); + path.append(pathIterator, connect); + updateBoundsFromShape(); + firePropertyChange(-1, "path", oldPath, getPath()); + } + + /** + * Add a curved segment, defined by three new points, to this path node by drawing + * a Bézier curve that intersects both the current coordinates and the specified + * coordinates (x3,y3), using the specified points (x1,y1) + * and (x2,y2) as Bézier control points. All coordinates are specified in + * double precision. + * + * @param x1 x coordinate of the first Bézier control point + * @param y1 y coordinate of the first Bézier control point + * @param x2 x coordinate of the second Bézier control point + * @param y2 y coordinate of the second Bézier control point + * @param x3 x coordinate of the final end point + * @param y3 y coordinate of the final end point + */ + public final void curveTo(final double x1, + final double y1, + final double x2, + final double y2, + final double x3, + final double y3) { + Path2D oldPath = (Path2D) path.clone(); + path.curveTo(x1, y1, x2, y2, x3, y3); + updateBoundsFromShape(); + firePropertyChange(-1, "path", oldPath, getPath()); + } + + /** + * Add a point to this path node by drawing a straight line from the + * current coordinates to the new specified coordinates specified in double precision. + * + * @param x x coordinate + * @param y y coordinate + */ + public final void lineTo(final double x, final double y) { + Path2D oldPath = (Path2D) path.clone(); + path.lineTo(x, y); + updateBoundsFromShape(); + firePropertyChange(-1, "path", oldPath, getPath()); + } + + /** + * Add a point to this path node by moving to the specified coordinates + * specified in double precision. + * + * @param x x coordinate + * @param y y coordinate + */ + public final void moveTo(final double x, final double y) { + Path2D oldPath = (Path2D) path.clone(); + path.moveTo(x, y); + updateBoundsFromShape(); + firePropertyChange(-1, "path", oldPath, getPath()); + } + + /** + * Add a curved segment, defined by two new points, to this path node by + * drawing a Quadratic curve that intersects both the current coordinates and + * the specified coordinates (x2,y2), using the specified point + * (x1,y1) as a quadratic parametric control point. All coordinates + * are specified in double precision. + * + * @param x1 x coordinate of the quadratic control point + * @param y1 y coordinate of the quadratic control point + * @param x2 x coordinate of the final end point + * @param y2 y coordinate of the final end point + */ + public final void quadTo(final double x1, final double y1, final double x2, final double y2) { + Path2D oldPath = (Path2D) path.clone(); + path.quadTo(x1, y1, x2, y2); + updateBoundsFromShape(); + firePropertyChange(-1, "path", oldPath, getPath()); + } + + /** + * Close the current subpath by drawing a straight line back to the coordinates + * of the last moveTo. If the path is already closed then this method + * has no effect. + */ + public final void closePath() { + Path2D oldPath = (Path2D) path.clone(); + path.closePath(); + updateBoundsFromShape(); + firePropertyChange(-1, "path", oldPath, getPath()); + } + + // todo: setPathTo... + + /** {@inheritDoc} */ + protected final Shape getShape() { + return path; + } + + /** {@inheritDoc} */ + protected final void transform(final AffineTransform transform) { + path.transform(transform); + } +} \ No newline at end of file diff --git a/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/PShape.java b/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/PShape.java new file mode 100644 index 0000000..1dca8e0 --- /dev/null +++ b/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/PShape.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.nodes; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.Shape; +import java.awt.Stroke; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.piccolo2d.PNode; + +import org.piccolo2d.util.PPaintContext; + +/** + * Abstract shape node. + */ +public abstract class PShape extends PNode { + + /** Stroke for this shape node, defaults to {@link #DEFAULT_STROKE}. */ + private transient Stroke stroke = DEFAULT_STROKE; + + /** Stroke paint for this shape node, defaults to {@link #DEFAULT_STROKE_PAINT}. */ + private Paint strokePaint = DEFAULT_STROKE_PAINT; + + /** True if bounds are currently being updated to match the shape. */ + private transient boolean updatingBoundsFromShape = false; + + /** Default paint for this shape node, Color.WHITE. */ + public static final Paint DEFAULT_PAINT = Color.WHITE; + + /** Default stroke, a basic stroke of width 1.0f. */ + public static final Stroke DEFAULT_STROKE = new BasicStroke(1.0f); + + /** Default stroke paint, Color.BLACK. */ + public static final Paint DEFAULT_STROKE_PAINT = Color.BLACK; + + + /** + * This is an abstract class that cannot be instantiated directly. + */ + protected PShape() { + super(); + setPaint(DEFAULT_PAINT); + } + + + /** + * Return the shape for this shape node. + * + * @return the shape for this shape node + */ + protected abstract Shape getShape(); + + /** + * Apply the specified transform to the shape for this shape node. + * + * @param transform transform to apply to the shape for this shape node + */ + protected abstract void transform(AffineTransform transform); + + + /** + * Return the stroke for this shape node. Defaults to {@link #DEFAULT_STROKE}. + * + * @return the stroke for this shape node + */ + public final Stroke getStroke() { + return stroke; + } + + /** + * Set the stroke for this shape node to stroke. This is + * a bound property. + * + * @param stroke stroke for this shape node + */ + public final void setStroke(final Stroke stroke) { + Stroke oldStroke = this.stroke; + this.stroke = stroke; + updateBoundsFromShape(); + invalidatePaint(); + firePropertyChange(-1, "stroke", oldStroke, this.stroke); + } + + /** + * Return the stroke paint for this shape node. Defaults to {@link #DEFAULT_STROKE_PAINT}. + * + * @return the stroke paint for this shape node + */ + public final Paint getStrokePaint() { + return strokePaint; + } + + /** + * Set the stroke paint for this shape node to strokePaint. This is + * a bound property. + * + * @param strokePaint stroke paint for this shape node + */ + public final void setStrokePaint(final Paint strokePaint) { + Paint oldStrokePaint = this.strokePaint; + this.strokePaint = strokePaint; + invalidatePaint(); + firePropertyChange(-1, "strokePaint", oldStrokePaint, this.strokePaint); + } + + /** + * Update the bounds of this shape node from its shape. + */ + protected final void updateBoundsFromShape() { + updatingBoundsFromShape = true; + final Rectangle2D b = getBoundsWithStroke(); + setBounds(b.getX(), b.getY(), b.getWidth(), b.getHeight()); + updatingBoundsFromShape = false; + } + + /** + * Return the bounds of this node, taking the stroke into consideration if necessary. + * + * @return the bounds of this node, taking the stroke into consideration if necessary + */ + protected final Rectangle2D getBoundsWithStroke() { + if (stroke != null) { + return stroke.createStrokedShape(getShape()).getBounds2D(); + } + else { + return getShape().getBounds2D(); + } + } + + /** {@inheritDoc} */ + protected final void internalUpdateBounds(final double x, final double y, final double width, final double height) { + if (updatingBoundsFromShape) { + return; + } + + final Rectangle2D bounds = getShape().getBounds2D(); + final Rectangle2D strokeBounds = getBoundsWithStroke(); + final double strokeOutset = Math.max(strokeBounds.getWidth() - bounds.getWidth(), + strokeBounds.getHeight() - bounds.getHeight()); + + double adjustedX = x + strokeOutset / 2.0d; + double adjustedY = y + strokeOutset / 2.0d; + double adjustedWidth = width - strokeOutset; + double adjustedHeight = height - strokeOutset; + + final double scaleX; + if (adjustedWidth == 0 || bounds.getWidth() == 0) { + scaleX = 1.0d; + } + else { + scaleX = adjustedWidth / bounds.getWidth(); + } + final double scaleY; + if (adjustedHeight == 0 || bounds.getHeight() == 0) { + scaleY = 1.0d; + } + else { + scaleY = adjustedHeight / bounds.getHeight(); + } + + final AffineTransform transform = new AffineTransform(); + transform.translate(adjustedX, adjustedY); + transform.scale(scaleX, scaleY); + transform.translate(-bounds.getX(), -bounds.getY()); + transform(transform); + } + + /** {@inheritDoc} */ + public final boolean intersects(final Rectangle2D bounds) { + if (super.intersects(bounds)) { + if (getPaint() != null && getShape().intersects(bounds)) { + return true; + } + else if (stroke != null && strokePaint != null) { + return stroke.createStrokedShape(getShape()).intersects(bounds); + } + } + return false; + } + + /** {@inheritDoc} */ + protected final void paint(final PPaintContext paintContext) { + final Paint p = getPaint(); + final Graphics2D g2 = paintContext.getGraphics(); + + if (p != null) { + g2.setPaint(p); + g2.fill(getShape()); + } + + if (stroke != null && strokePaint != null) { + g2.setPaint(strokePaint); + g2.setStroke(stroke); + g2.draw(getShape()); + } + } +} \ No newline at end of file diff --git a/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/package-info.java b/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/package-info.java new file mode 100644 index 0000000..0e3bfdc --- /dev/null +++ b/jdk16/src/main/java/org/piccolo2d/jdk16/nodes/package-info.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Piccolo2D nodes that require a minimum JDK version of 1.6. + */ +package org.piccolo2d.jdk16.nodes; \ No newline at end of file diff --git a/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/AbstractPPathTest.java b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/AbstractPPathTest.java new file mode 100644 index 0000000..617e5d2 --- /dev/null +++ b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/AbstractPPathTest.java @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.nodes; + +import java.awt.Color; +import java.awt.Shape; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Arc2D; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; + +import org.piccolo2d.util.PBounds; +import org.piccolo2d.util.PObjectOutputStream; + +/** + * Abstract unit test for subclasses of PPath. + */ +public abstract class AbstractPPathTest extends AbstractPShapeTest { + + private static final double TOLERANCE = 0.0001d; + private static final double LOW_TOLERANCE = 1.0d; + + /** {@inheritDoc} */ + protected void setUp() { + super.setUp(); + } + + /** {@inheritDoc} */ + protected PShape createShapeNode() { + return createPathNode(); + } + + /** + * Create a new instance of a subclass of PPath to test. + * + * @return a new instance of a subclass of PPath to test + */ + protected abstract PPath createPathNode(); + + // todo: rewrite in terms of createPathNode() + + public void testClone() { + PPath p = PPath.createEllipse(0, 0, 100, 100); + PPath cloned = (PPath) p.clone(); + assertEquals(p.getBounds(), cloned.getBounds()); + //assertEquals(p.getPathReference()., cloned.getPathReference()); + } + + public void testSerialization() throws IOException, ClassNotFoundException { + final PPath srcPath = PPath.createEllipse(0, 0, 100, 100); + final PBounds srcBounds = srcPath.getBounds(); + + final File file = File.createTempFile("test", "ser"); + + serializeToFile(srcPath, file); + final PPath resultPath = deserializeFromFile(srcBounds, file); + file.deleteOnExit(); + + assertEquals(resultPath.getBounds(), srcBounds); + } + + private PPath deserializeFromFile(final PBounds b, final File file) throws FileNotFoundException, IOException, + ClassNotFoundException { + PPath path; + final FileInputStream fin = new FileInputStream(file); + final ObjectInputStream in = new ObjectInputStream(fin); + path = (PPath) in.readObject(); + + return path; + } + + private void serializeToFile(final PPath p, final File file) throws FileNotFoundException, IOException { + final FileOutputStream fout = new FileOutputStream(file); + final PObjectOutputStream out = new PObjectOutputStream(fout); + out.writeObjectTree(p); + out.flush(); + out.close(); + } + + public void testCreateArcFloat() { + assertNotNull(PPath.createArc(0.0f, 0.0f, 50.0f, 100.0f, 25.0f, 75.0f, Arc2D.OPEN)); + } + + public void testCreateCubicCurveFloat() { + assertNotNull(PPath.createCubicCurve(0.0f, 0.0f, 25.0f, 75.0f, 75.0f, 25.0f, 50.0f, 100.0f)); + } + + public void testCreateEllipseFloat() { + assertNotNull(PPath.createEllipse(0.0f, 0.0f, 50.0f, 100.0f)); + } + + public void testCreateLineFloat() { + assertNotNull(PPath.createLine(0.0f, 0.0f, 50.0f, 100.0f)); + } + + public void testCreateQuadCurveFloat() { + assertNotNull(PPath.createQuadCurve(0.0f, 0.0f, 25.0f, 75.0f, 50.0f, 100.0f)); + } + + public void testCreateRectangleFloat() { + assertNotNull(PPath.createRectangle(0.0f, 0.0f, 50.0f, 100.0f)); + } + + public void testCreateRoundRectangleFloat() { + assertNotNull(PPath.createRoundRectangle(0.0f, 0.0f, 50.0f, 100.0f, 4.0f, 8.0f)); + } + + public void testCreateArcDouble() { + assertNotNull(PPath.createArc(0.0d, 0.0d, 50.0d, 100.0d, 25.0d, 75.0d, Arc2D.OPEN)); + } + + public void testCreateCubicCurveDouble() { + assertNotNull(PPath.createCubicCurve(0.0d, 0.0d, 25.0d, 75.0d, 75.0d, 25.0d, 50.0d, 100.0d)); + } + + public void testCreateEllipseDouble() { + assertNotNull(PPath.createEllipse(0.0d, 0.0d, 50.0d, 100.0d)); + } + + public void testCreateLineDouble() { + assertNotNull(PPath.createLine(0.0d, 0.0d, 50.0d, 100.0d)); + } + + public void testCreateQuadCurveDouble() { + assertNotNull(PPath.createQuadCurve(0.0d, 0.0d, 25.0d, 75.0d, 50.0d, 100.0d)); + } + + public void testCreateRectangleDouble() { + assertNotNull(PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d)); + } + + public void testCreateRoundRectangleDouble() { + assertNotNull(PPath.createRoundRectangle(0.0d, 0.0d, 50.0d, 100.0d, 4.0d, 8.0d)); + } + + public void testAppendShape() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + Rectangle2D rect = new Rectangle2D.Double(50.0d, 100.0d, 50.0d, 100.0d); + path.append(rect, true); + // todo: shouldn't this be width + 2 * strokeWidth? + assertEquals(101.0d, path.getWidth(), TOLERANCE); + assertEquals(201.0d, path.getHeight(), TOLERANCE); + } + + public void testAppendShapeNullArgument() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + try { + path.append((Shape) null, true); + fail("append((Shape) null, true) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testAppendPathIterator() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + Rectangle2D rect = new Rectangle2D.Double(50.0d, 100.0d, 50.0d, 100.0d); + PathIterator pathIterator = rect.getPathIterator(new AffineTransform()); + path.append(pathIterator, true); + assertEquals(101.0d, path.getWidth(), TOLERANCE); + assertEquals(201.0d, path.getHeight(), TOLERANCE); + } + + public void testAppendPathIteratorNullArgument() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + try { + path.append((PathIterator) null, true); + fail("append((PathIterator) null, true) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testCurveTo() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.curveTo(70.0d, 140.0d, 80.0d, 140.0d, 100.0d, 200.0d); + assertEquals(101.0d, path.getWidth(), LOW_TOLERANCE); + assertEquals(201.0d, path.getHeight(), LOW_TOLERANCE); + } + + public void testLineTo() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.lineTo(100.0d, 200.0d); + assertEquals(101.0d, path.getWidth(), LOW_TOLERANCE); + assertEquals(201.0d, path.getHeight(), LOW_TOLERANCE); + } + + public void testMoveTo() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.moveTo(100.0d, 200.0d); + assertEquals(51.0d, path.getWidth(), TOLERANCE); + assertEquals(101.0d, path.getHeight(), TOLERANCE); + } + + public void testQuadTo() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.quadTo(70.0d, 140.0d, 100.0d, 200.0d); + assertEquals(101.0d, path.getWidth(), LOW_TOLERANCE); + assertEquals(201.0d, path.getHeight(), LOW_TOLERANCE); + } + + public void testClosePath() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.lineTo(100.0d, 200.0d); + path.closePath(); + } + + public void testClosePathAlreadyClosed() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.lineTo(100.0d, 200.0d); + path.closePath(); + path.closePath(); + } + + public void testIntersects() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + assertTrue(path.intersects(new Rectangle2D.Double(0.0d, 0.0d, 2.0d, 2.0d))); + assertTrue(path.intersects(new Rectangle2D.Double(25.0d, 50.0d, 2.0d, 2.0d))); + assertTrue(path.intersects(new Rectangle2D.Double(49.0d, 99.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(-10.0d, -10.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(100.0d, 200.0d, 2.0d, 2.0d))); + } + + public void testIntersectsNullStroke() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.setStroke(null); + assertTrue(path.intersects(new Rectangle2D.Double(0.0d, 0.0d, 2.0d, 2.0d))); + assertTrue(path.intersects(new Rectangle2D.Double(25.0d, 50.0d, 2.0d, 2.0d))); + assertTrue(path.intersects(new Rectangle2D.Double(49.0d, 99.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(-10.0d, -10.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(100.0d, 200.0d, 2.0d, 2.0d))); + } + + public void testIntersectsNullPaint() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.setPaint(null); + assertTrue(path.intersects(new Rectangle2D.Double(0.0d, 0.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(25.0d, 50.0d, 2.0d, 2.0d))); + assertTrue(path.intersects(new Rectangle2D.Double(49.0d, 99.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(-10.0d, -10.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(100.0d, 200.0d, 2.0d, 2.0d))); + } + + public void testIntersectsNullPaintNullStroke() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.setPaint(null); + path.setStroke(null); + assertFalse(path.intersects(new Rectangle2D.Double(0.0d, 0.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(25.0d, 50.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(49.0d, 99.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(-10.0d, -10.0d, 2.0d, 2.0d))); + assertFalse(path.intersects(new Rectangle2D.Double(100.0d, 200.0d, 2.0d, 2.0d))); + } + + public void testFullIntersects() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + assertTrue(path.fullIntersects(new Rectangle2D.Double(0.0d, 0.0d, 2.0d, 2.0d))); + assertTrue(path.fullIntersects(new Rectangle2D.Double(25.0d, 50.0d, 2.0d, 2.0d))); + assertTrue(path.fullIntersects(new Rectangle2D.Double(49.0d, 99.0d, 2.0d, 2.0d))); + assertFalse(path.fullIntersects(new Rectangle2D.Double(-10.0d, -10.0d, 2.0d, 2.0d))); + assertFalse(path.fullIntersects(new Rectangle2D.Double(100.0d, 200.0d, 2.0d, 2.0d))); + } + + public void testFullIntersectsNullStroke() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.setStroke(null); + assertTrue(path.fullIntersects(new Rectangle2D.Double(0.0d, 0.0d, 2.0d, 2.0d))); + assertTrue(path.fullIntersects(new Rectangle2D.Double(25.0d, 50.0d, 2.0d, 2.0d))); + assertTrue(path.fullIntersects(new Rectangle2D.Double(49.0d, 99.0d, 2.0d, 2.0d))); + assertFalse(path.fullIntersects(new Rectangle2D.Double(-10.0d, -10.0d, 2.0d, 2.0d))); + assertFalse(path.fullIntersects(new Rectangle2D.Double(100.0d, 200.0d, 2.0d, 2.0d))); + } + + public void testFullIntersectsNullPaint() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.setPaint(null); + assertTrue(path.fullIntersects(new Rectangle2D.Double(0.0d, 0.0d, 2.0d, 2.0d))); + assertTrue(path.fullIntersects(new Rectangle2D.Double(25.0d, 50.0d, 2.0d, 2.0d))); + assertTrue(path.fullIntersects(new Rectangle2D.Double(49.0d, 99.0d, 2.0d, 2.0d))); + assertFalse(path.fullIntersects(new Rectangle2D.Double(-10.0d, -10.0d, 2.0d, 2.0d))); + assertFalse(path.fullIntersects(new Rectangle2D.Double(100.0d, 200.0d, 2.0d, 2.0d))); + } + + public void testFullIntersectsNullPaintNullStroke() { + PPath path = PPath.createRectangle(0.0d, 0.0d, 50.0d, 100.0d); + path.setPaint(null); + path.setStroke(null); + assertTrue(path.fullIntersects(new Rectangle2D.Double(0.0d, 0.0d, 2.0d, 2.0d))); + assertTrue(path.fullIntersects(new Rectangle2D.Double(25.0d, 50.0d, 2.0d, 2.0d))); + assertTrue(path.fullIntersects(new Rectangle2D.Double(49.0d, 99.0d, 2.0d, 2.0d))); + assertFalse(path.fullIntersects(new Rectangle2D.Double(-10.0d, -10.0d, 2.0d, 2.0d))); + assertFalse(path.fullIntersects(new Rectangle2D.Double(100.0d, 200.0d, 2.0d, 2.0d))); + } + + /* + public void testPath() { + PPath path = createPathNode(); + assertNotNull(path.getPath()); // or (Path) getShape(), or getPathReference() ? + Path2D.Double rect = new Path2D.Double((new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d))); + path.setPath(rect); + assertEquals(rect, path.getPath()); + } + + public void testPathNullArgument() { + PPath path = createPathNode(); + try { + path.setPath(null); + fail("setPath(null) expected IllegalArgumentException"); + } + catch (IllegalArgumentException e) { // or NPE? + // expected + } + } + + public void testPathBoundProperty() { + PPath path = createPathNode(); + path.addPropertyChangeListener("path", mockListener); + Path2D.Double rect = new Path2D.Double((new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d))); + path.setPath(rect); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + */ + + public void testAppendShapeFiresPropertyChangeEvent() { + PPath path = createPathNode(); + path.addPropertyChangeListener("path", mockListener); + Rectangle2D rect = new Rectangle2D.Double(50.0d, 100.0d, 50.0d, 100.0d); + path.append(rect, true); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testAppendPathIteratorFiresPropertyChangeEvent() { + PPath path = createPathNode(); + path.moveTo(0.0d, 0.0d); + path.addPropertyChangeListener("path", mockListener); + Rectangle2D rect = new Rectangle2D.Double(50.0d, 100.0d, 50.0d, 100.0d); + PathIterator pathIterator = rect.getPathIterator(new AffineTransform()); + path.append(pathIterator, true); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testCurveToFiresPropertyChangeEvent() { + PPath path = createPathNode(); + path.moveTo(0.0d, 0.0d); + path.addPropertyChangeListener("path", mockListener); + path.curveTo(70.0d, 140.0d, 80.0d, 140.0d, 100.0d, 200.0d); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testLineToFiresPropertyChangeEvent() { + PPath path = createPathNode(); + path.moveTo(0.0d, 0.0d); + path.addPropertyChangeListener("path", mockListener); + path.lineTo(100.0d, 200.0d); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testMoveToFiresPropertyChangeEvent() { + PPath path = createPathNode(); + path.moveTo(0.0d, 0.0d); + path.addPropertyChangeListener("path", mockListener); + path.moveTo(100.0d, 200.0d); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testQuadToFiresPropertyChangeEvent() { + PPath path = createPathNode(); + path.moveTo(0.0d, 0.0d); + path.addPropertyChangeListener("path", mockListener); + path.quadTo(70.0d, 140.0d, 100.0d, 200.0d); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testClosePathFiresPropertyChangeEvent() { + PPath path = createPathNode(); + path.moveTo(0.0d, 0.0d); + path.lineTo(100.0d, 200.0d); + path.addPropertyChangeListener("path", mockListener); + path.closePath(); + assertEquals(1, mockListener.getPropertyChangeCount()); + } +} diff --git a/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/AbstractPShapeTest.java b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/AbstractPShapeTest.java new file mode 100644 index 0000000..8e2c51c --- /dev/null +++ b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/AbstractPShapeTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.nodes; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Paint; +import java.awt.Stroke; + +import junit.framework.TestCase; + +/** + * Abstract unit test for subclasses of PShape. + */ +public abstract class AbstractPShapeTest extends TestCase { + + /** Mock property change listener. */ + protected MockPropertyChangeListener mockListener; + + + /** {@inheritDoc} */ + protected void setUp() { + mockListener = new MockPropertyChangeListener(); + } + + /** + * Create a new instance of a subclass of PShape to test. + * + * @return a new instance of a subclass of PShape to test + */ + protected abstract PShape createShapeNode(); + + public void testCreateShapeNode() { + assertNotNull(createShapeNode()); + } + + public void testDefaultPaint() { + PShape shape = createShapeNode(); + assertEquals(PShape.DEFAULT_PAINT, shape.getPaint()); + } + + public void testDefaultStroke() { + PShape shape = createShapeNode(); + assertEquals(PShape.DEFAULT_STROKE, shape.getStroke()); + } + + public void testDefaultStrokePaint() { + PShape shape = createShapeNode(); + assertEquals(PShape.DEFAULT_STROKE_PAINT, shape.getStrokePaint()); + } + + public void testStroke() { + PShape shape = createShapeNode(); + Stroke stroke = new BasicStroke(2.0f); + shape.setStroke(stroke); + assertEquals(stroke, shape.getStroke()); + } + + public void testStrokeBoundProperty() { + PShape shape = createShapeNode(); + shape.addPropertyChangeListener("stroke", mockListener); + Stroke stroke = new BasicStroke(2.0f); + shape.setStroke(stroke); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testStrokePaint() { + PShape shape = createShapeNode(); + Paint strokePaint = Color.RED; + shape.setStrokePaint(strokePaint); + assertEquals(strokePaint, shape.getStrokePaint()); + } + + public void testStrokePaintBoundProperty() { + PShape shape = createShapeNode(); + shape.addPropertyChangeListener("strokePaint", mockListener); + Paint strokePaint = Color.RED; + shape.setStrokePaint(strokePaint); + assertEquals(1, mockListener.getPropertyChangeCount()); + } +} \ No newline at end of file diff --git a/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/MockPropertyChangeListener.java b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/MockPropertyChangeListener.java new file mode 100644 index 0000000..46572bf --- /dev/null +++ b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/MockPropertyChangeListener.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.nodes; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import java.util.ArrayList; +import java.util.List; + +/** + * Mock PropertyChangeListener. + */ +public class MockPropertyChangeListener implements PropertyChangeListener { + private final List changes = new ArrayList(); + + public void propertyChange(final PropertyChangeEvent evt) { + changes.add(evt); + } + + public int getPropertyChangeCount() { + return changes.size(); + } + + public PropertyChangeEvent getPropertyChange(final int index) { + return (PropertyChangeEvent) changes.get(index); + } +} \ No newline at end of file diff --git a/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/PAreaTest.java b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/PAreaTest.java new file mode 100644 index 0000000..e808d90 --- /dev/null +++ b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/PAreaTest.java @@ -0,0 +1,632 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.nodes; + +import java.awt.Shape; + +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; + +/** + * Unit test for PArea. + */ +public class PAreaTest extends AbstractPShapeTest { + + private static final double TOLERANCE = 0.0001d; + private static final Rectangle2D FIRST = new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d); + private static final Rectangle2D SECOND = new Rectangle2D.Double(50.0, 50.0d, 100.0d, 100.0d); + private static final Rectangle2D FIRST_INTERIOR = new Rectangle2D.Double(25.0d, 25.0d, 2.0d, 2.0d); + private static final Rectangle2D FIRST_PATH = new Rectangle2D.Double(25.0d, 100.0d, 1.0d, 1.0d); + private static final Rectangle2D SECOND_INTERIOR = new Rectangle2D.Double(125.0d, 125.0d, 2.0d, 2.0d); + private static final Rectangle2D SECOND_PATH = new Rectangle2D.Double(125.0d, 150.0d, 1.0d, 1.0d); + private static final Rectangle2D INTERSECTION_INTERIOR = new Rectangle2D.Double(75.0, 75.0d, 2.0d, 2.0d); + private static final Rectangle2D INTERSECTION_PATH = new Rectangle2D.Double(75.0, 100.0d, 1.0d, 1.0d); + private static final Rectangle2D EXTERIOR = new Rectangle2D.Double(200.0, 200.0d, 2.0d, 2.0d); + + /** {@inheritDoc} */ + protected void setUp() { + super.setUp(); + } + + /** {@inheritDoc} */ + protected PShape createShapeNode() { + return new PArea(); + } + + public void testNoArgConstructor() { + assertNotNull(new PArea()); + } + + public void testShapeConstructor() { + assertNotNull(new PArea(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d))); + } + + public void testShapeConstructorNullArgument() { + try { + new PArea((Shape) null); + fail("ctr((Shape) null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testAreaConstructor() { + assertNotNull(new PArea(new Area())); + } + + public void testAreaConstructorNullArgument() { + try { + new PArea((Area) null); + fail("ctr((Area) null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testAdd() { + PArea area = new PArea(); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.add(rect1); + + // todo: shouldn't this be width + 2 * strokeWidth? + assertEquals(151.0d, area.getWidth(), TOLERANCE); + assertEquals(151.0d, area.getHeight(), TOLERANCE); + + assertTrue(area.intersects(FIRST_INTERIOR)); + assertTrue(area.intersects(FIRST_PATH)); + assertTrue(area.intersects(SECOND_INTERIOR)); + assertTrue(area.intersects(SECOND_PATH)); + assertTrue(area.intersects(INTERSECTION_INTERIOR)); + assertTrue(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testAddNullPaint() { + PArea area = new PArea(); + area.setPaint(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.add(rect1); + + assertEquals(151.0d, area.getWidth(), TOLERANCE); + assertEquals(151.0d, area.getHeight(), TOLERANCE); + + assertFalse(area.intersects(FIRST_INTERIOR)); + assertTrue(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertTrue(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertFalse(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testAddNullStroke() { + PArea area = new PArea(); + area.setStroke(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.add(rect1); + + assertEquals(150.0d, area.getWidth(), TOLERANCE); + assertEquals(150.0d, area.getHeight(), TOLERANCE); + + assertTrue(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertTrue(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertTrue(area.intersects(INTERSECTION_INTERIOR)); + assertTrue(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testAddNullStrokePaint() { + PArea area = new PArea(); + area.setStrokePaint(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.add(rect1); + + assertEquals(151.0d, area.getWidth(), TOLERANCE); + assertEquals(151.0d, area.getHeight(), TOLERANCE); + + assertTrue(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertTrue(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertTrue(area.intersects(INTERSECTION_INTERIOR)); + assertTrue(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testAddNullArgument() { + PArea area = new PArea(); + try { + area.add(null); + fail("add(null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testExclusiveOr() { + PArea area = new PArea(); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.exclusiveOr(rect1); + + assertEquals(151.0d, area.getWidth(), TOLERANCE); + assertEquals(151.0d, area.getHeight(), TOLERANCE); + + assertTrue(area.intersects(FIRST_INTERIOR)); + assertTrue(area.intersects(FIRST_PATH)); + assertTrue(area.intersects(SECOND_INTERIOR)); + assertTrue(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertTrue(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testExclusiveOrNullPaint() { + PArea area = new PArea(); + area.setPaint(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.exclusiveOr(rect1); + + assertEquals(151.0d, area.getWidth(), TOLERANCE); + assertEquals(151.0d, area.getHeight(), TOLERANCE); + + assertFalse(area.intersects(FIRST_INTERIOR)); + assertTrue(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertTrue(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertTrue(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testExclusiveOrNullStroke() { + PArea area = new PArea(); + area.setStroke(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.exclusiveOr(rect1); + + assertEquals(150.0d, area.getWidth(), TOLERANCE); + assertEquals(150.0d, area.getHeight(), TOLERANCE); + + assertTrue(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertTrue(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertTrue(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testExclusiveOrNullStrokePaint() { + PArea area = new PArea(); + area.setStrokePaint(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.exclusiveOr(rect1); + + assertEquals(151.0d, area.getWidth(), TOLERANCE); + assertEquals(151.0d, area.getHeight(), TOLERANCE); + + assertTrue(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertTrue(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertTrue(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testExclusiveOrNullArgument() { + PArea area = new PArea(); + try { + area.exclusiveOr(null); + fail("exclusiveOr(null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testIntersect() { + PArea area = new PArea(); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.intersect(rect1); + + assertEquals(51.0d, area.getWidth(), TOLERANCE); + assertEquals(51.0d, area.getHeight(), TOLERANCE); + + assertFalse(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertTrue(area.intersects(INTERSECTION_INTERIOR)); + assertTrue(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testIntersectNullPaint() { + PArea area = new PArea(); + area.setPaint(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.intersect(rect1); + + assertEquals(51.0d, area.getWidth(), TOLERANCE); + assertEquals(51.0d, area.getHeight(), TOLERANCE); + + assertFalse(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertTrue(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testIntersectNullStroke() { + PArea area = new PArea(); + area.setStroke(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.intersect(rect1); + + assertEquals(50.0d, area.getWidth(), TOLERANCE); + assertEquals(50.0d, area.getHeight(), TOLERANCE); + + assertFalse(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertTrue(area.intersects(INTERSECTION_INTERIOR)); + assertFalse(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testIntersectNullStrokePaint() { + PArea area = new PArea(); + area.setStrokePaint(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.intersect(rect1); + + assertEquals(51.0d, area.getWidth(), TOLERANCE); + assertEquals(51.0d, area.getHeight(), TOLERANCE); + + assertFalse(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertTrue(area.intersects(INTERSECTION_INTERIOR)); + assertFalse(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testIntersectNullArgument() { + PArea area = new PArea(); + try { + area.intersect(null); + fail("intersect(null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testSubtract() { + PArea area = new PArea(); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.subtract(rect1); + + assertEquals(101.0d, area.getWidth(), TOLERANCE); + assertEquals(101.0d, area.getHeight(), TOLERANCE); + + assertTrue(area.intersects(FIRST_INTERIOR)); + assertTrue(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertFalse(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testSubtractNullPaint() { + PArea area = new PArea(); + area.setPaint(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.subtract(rect1); + + assertEquals(101.0d, area.getWidth(), TOLERANCE); + assertEquals(101.0d, area.getHeight(), TOLERANCE); + + assertFalse(area.intersects(FIRST_INTERIOR)); + assertTrue(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertFalse(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testSubtractNullStroke() { + PArea area = new PArea(); + area.setStroke(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.subtract(rect1); + + assertEquals(100.0d, area.getWidth(), TOLERANCE); + assertEquals(100.0d, area.getHeight(), TOLERANCE); + + assertTrue(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertFalse(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testSubtractNullStrokePaint() { + PArea area = new PArea(); + area.setStrokePaint(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(FIRST); + area.add(rect0); + Area rect1 = new Area(SECOND); + area.subtract(rect1); + + assertEquals(101.0d, area.getWidth(), TOLERANCE); + assertEquals(101.0d, area.getHeight(), TOLERANCE); + + assertTrue(area.intersects(FIRST_INTERIOR)); + assertFalse(area.intersects(FIRST_PATH)); + assertFalse(area.intersects(SECOND_INTERIOR)); + assertFalse(area.intersects(SECOND_PATH)); + assertFalse(area.intersects(INTERSECTION_INTERIOR)); + assertFalse(area.intersects(INTERSECTION_PATH)); + assertFalse(area.intersects(EXTERIOR)); + } + + public void testSubtractNullArgument() { + PArea area = new PArea(); + try { + area.subtract(null); + fail("subtract(null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testReset() { + PArea area = new PArea(); + area.setStroke(null); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + + Area rect0 = new Area(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d)); + area.add(rect0); + Area rect1 = new Area(new Rectangle2D.Double(50.0d, 0.0d, 100.0d, 100.0d)); + area.add(rect1); + + assertEquals(150.0d, area.getWidth(), TOLERANCE); + assertEquals(100.0, area.getHeight(), TOLERANCE); + + area.reset(); + assertEquals(0.0d, area.getWidth(), TOLERANCE); + assertEquals(0.0d, area.getHeight(), TOLERANCE); + } + + public void testIsEmpty() { + assertTrue(new PArea().isEmpty()); + assertFalse(new PArea(new Rectangle2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isEmpty()); + assertTrue(new PArea(new Line2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isEmpty()); + assertFalse(new PArea(new Ellipse2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isEmpty()); + } + + public void testIsPolygonal() { + assertTrue(new PArea(new Rectangle2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isPolygonal()); + assertTrue(new PArea(new Line2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isPolygonal()); + assertFalse(new PArea(new Ellipse2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isPolygonal()); + } + + public void testIsRectangular() { + assertTrue(new PArea(new Rectangle2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isRectangular()); + assertTrue(new PArea(new Line2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isRectangular()); + assertFalse(new PArea(new Ellipse2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isRectangular()); + } + + public void testIsSingular() { + assertTrue(new PArea(new Rectangle2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isSingular()); + assertTrue(new PArea(new Line2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isSingular()); + assertTrue(new PArea(new Ellipse2D.Double(0.0d, 0.0d, 50.0d, 100.0d)).isSingular()); + + PArea exclusiveOr = new PArea(); + Area rect0 = new Area(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d)); + exclusiveOr.add(rect0); + Area rect1 = new Area(new Rectangle2D.Double(50.0d, 0.0d, 100.0d, 100.0d)); + exclusiveOr.exclusiveOr(rect1); + + assertFalse(exclusiveOr.isSingular()); + } + + /* + public void testArea() { + PArea area = new PArea(); + assertNotNull(area.getArea()); // or (Area) getShape(), or getAreaReference() ? + Area rect = new Area(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d)); + area.setArea(rect); + assertEquals(rect, area.getArea()); + } + + public void testAreaNullArgument() { + PArea area = new PArea(); + try { + area.setArea(null); + fail("setArea(null) expected IllegalArgumentException"); + } + catch (IllegalArgumentException e) { // or NPE? + // expected + } + } + + public void testAreaBoundProperty() { + PArea area = new PArea(); + area.addPropertyChangeListener("area", mockListener); + Area rect = new Area(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d)); + area.setArea(rect); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + */ + + public void testAddFiresPropertyChangeEvent() { + PArea area = new PArea(); + area.addPropertyChangeListener("area", mockListener); + Area rect = new Area(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d)); + area.add(rect); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testExclusiveOrFiresPropertyChangeEvent() { + PArea area = new PArea(); + Area rect0 = new Area(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d)); + area.add(rect0); + Area rect1 = new Area(new Rectangle2D.Double(50.0d, 0.0d, 100.0d, 100.0d)); + area.addPropertyChangeListener("area", mockListener); + area.exclusiveOr(rect1); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testIntersectFiresPropertyChangeEvent() { + PArea area = new PArea(); + Area rect0 = new Area(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d)); + area.add(rect0); + Area rect1 = new Area(new Rectangle2D.Double(50.0d, 0.0d, 100.0d, 100.0d)); + area.addPropertyChangeListener("area", mockListener); + area.intersect(rect1); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testSubtractFiresPropertyChangeEvent() { + PArea area = new PArea(); + Area rect0 = new Area(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d)); + area.add(rect0); + Area rect1 = new Area(new Rectangle2D.Double(50.0d, 0.0d, 100.0d, 100.0d)); + area.addPropertyChangeListener("area", mockListener); + area.subtract(rect1); + assertEquals(1, mockListener.getPropertyChangeCount()); + } + + public void testResetFiresPropertyChangeEvent() { + PArea area = new PArea(); + Area rect = new Area(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d)); + area.add(rect); + area.addPropertyChangeListener("area", mockListener); + area.reset(); + assertEquals(1, mockListener.getPropertyChangeCount()); + } +} \ No newline at end of file diff --git a/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/PPathDoubleTest.java b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/PPathDoubleTest.java new file mode 100644 index 0000000..006aa7f --- /dev/null +++ b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/PPathDoubleTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.nodes; + +import java.awt.BasicStroke; +import java.awt.Shape; +import java.awt.Stroke; + +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; + +/** + * Unit test for PPath.Double. + */ +public class PPathDoubleTest extends AbstractPPathTest { + + /** {@inheritDoc} */ + protected PPath createPathNode() { + return new PPath.Double(); + } + + public void testNoArgConstructor() { + assertNotNull(new PPath.Double()); + } + + public void testStrokeConstructor() { + assertNotNull(new PPath.Double((Stroke) null)); + assertNotNull(new PPath.Double(new BasicStroke(2.0f))); + } + + public void testShapeConstructor() { + assertNotNull(new PPath.Double(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d))); + } + + public void testShapeStrokeConstructor() { + assertNotNull(new PPath.Double(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d), null)); + assertNotNull(new PPath.Double(new Rectangle2D.Double(0.0d, 0.0d, 100.0d, 100.0d), new BasicStroke(2.0f))); + } + + public void testShapeConstructorNullArgument() { + try { + new PPath.Double((Shape) null); + fail("ctr((Shape) null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testShapeStrokeConstructorNullArgument() { + try { + new PPath.Double((Shape) null, null); + fail("ctr((Shape) null, ) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testPathConstructor() { + assertNotNull(new PPath.Double(new Path2D.Double())); + } + + public void testPathStrokeConstructor() { + assertNotNull(new PPath.Double(new Path2D.Double(), null)); + assertNotNull(new PPath.Double(new Path2D.Double(), new BasicStroke(2.0f))); + } + + public void testPathConstructorNullArgument() { + try { + new PPath.Double((Path2D) null); + fail("ctr((Path2D) null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testPathStrokeConstructorNullArgument() { + try { + new PPath.Double((Path2D) null, null); + fail("ctr((Path2D) null, ) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } +} \ No newline at end of file diff --git a/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/PPathFloatTest.java b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/PPathFloatTest.java new file mode 100644 index 0000000..b43549b --- /dev/null +++ b/jdk16/src/test/java/org/piccolo2d/jdk16/nodes/PPathFloatTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2008-2010, Piccolo2D project, http://piccolo2d.org + * Copyright (c) 1998-2008, University of Maryland + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of conditions + * and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * None of the name of the University of Maryland, the name of the Piccolo2D project, or the names of its + * contributors may be used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.piccolo2d.jdk16.nodes; + +import java.awt.BasicStroke; +import java.awt.Shape; +import java.awt.Stroke; + +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; + +/** + * Unit test for PPath.Float. + */ +public class PPathFloatTest extends AbstractPPathTest { + + /** {@inheritDoc} */ + protected PPath createPathNode() { + return new PPath.Float(); + } + + public void testNoArgConstructor() { + assertNotNull(new PPath.Float()); + } + + public void testStrokeConstructor() { + assertNotNull(new PPath.Float((Stroke) null)); + assertNotNull(new PPath.Float(new BasicStroke(2.0f))); + } + + public void testShapeConstructor() { + assertNotNull(new PPath.Float(new Rectangle2D.Float(0.0f, 0.0f, 100.0f, 100.0f))); + } + + public void testShapeStrokeConstructor() { + assertNotNull(new PPath.Float(new Rectangle2D.Float(0.0f, 0.0f, 100.0f, 100.0f), null)); + assertNotNull(new PPath.Float(new Rectangle2D.Float(0.0f, 0.0f, 100.0f, 100.0f), new BasicStroke(2.0f))); + } + + public void testShapeConstructorNullArgument() { + try { + new PPath.Float((Shape) null); + fail("ctr((Shape) null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testShapeStrokeConstructorNullArgument() { + try { + new PPath.Float((Shape) null, null); + fail("ctr((Shape) null, ) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testPathConstructor() { + assertNotNull(new PPath.Float(new Path2D.Float())); + } + + public void testPathStrokeConstructor() { + assertNotNull(new PPath.Float(new Path2D.Float(), null)); + assertNotNull(new PPath.Float(new Path2D.Float(), new BasicStroke(2.0f))); + } + + public void testPathConstructorNullArgument() { + try { + new PPath.Float((Path2D) null); + fail("ctr((Path2D) null) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } + + public void testStrokePathConstructorNullArgument() { + try { + new PPath.Float((Path2D) null, null); + fail("ctr((Path2D) null, ) expected NullPointerException"); + } + catch (NullPointerException e) { + // expected + } + } +} \ No newline at end of file