diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java
index 0a2adb7..f8f856d 100644
--- a/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java
+++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java
@@ -111,9 +111,9 @@
KeyEventFocusExample.class, LayoutExample.class, LensExample.class, NavigationExample.class,
NodeCacheExample.class, NodeEventExample.class, NodeExample.class, NodeLinkExample.class,
PanToExample.class, PathExample.class, PositionExample.class, PositionPathActivityExample.class,
- PulseExample.class, ScrollingExample.class, SelectionExample.class, SquiggleExample.class,
- StickyExample.class, StickyHandleLayerExample.class, StrokeExample.class, TextExample.class,
- TooltipExample.class, TwoCanvasExample.class, WaitForActivitiesExample.class });
+ PulseExample.class, ScrollingExample.class, SelectionExample.class, ShadowExample.class,
+ SquiggleExample.class, StickyExample.class, StickyHandleLayerExample.class, StrokeExample.class,
+ TextExample.class, TooltipExample.class, TwoCanvasExample.class, WaitForActivitiesExample.class });
}
private void addExampleButtons(final JPanel panel, final Class[] exampleClasses) {
diff --git a/examples/src/main/java/edu/umd/cs/piccolo/examples/ShadowExample.java b/examples/src/main/java/edu/umd/cs/piccolo/examples/ShadowExample.java
new file mode 100755
index 0000000..7c68e3e
--- /dev/null
+++ b/examples/src/main/java/edu/umd/cs/piccolo/examples/ShadowExample.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2008-2009, 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 edu.umd.cs.piccolo.examples;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+
+import java.awt.image.BufferedImage;
+
+import edu.umd.cs.piccolo.PCanvas;
+
+import edu.umd.cs.piccolo.nodes.PImage;
+import edu.umd.cs.piccolo.nodes.PPath;
+import edu.umd.cs.piccolo.nodes.PText;
+
+import edu.umd.cs.piccolox.PFrame;
+
+import edu.umd.cs.piccolox.nodes.PShadow;
+
+/**
+ * Shadow example.
+ */
+public final class ShadowExample extends PFrame {
+
+ /**
+ * Create a new shadow example.
+ */
+ public ShadowExample() {
+ this(null);
+ }
+
+ /**
+ * Create a new shadow example with the specified canvas.
+ *
+ * @param canvas canvas for this shadow example
+ */
+ public ShadowExample(final PCanvas canvas) {
+ super("ShadowExample", false, canvas);
+ }
+
+
+ /** {@inheritDoc} */
+ public void initialize() {
+ BufferedImage src = new BufferedImage(75, 75, BufferedImage.TYPE_INT_ARGB);
+ Paint shadowPaint = new Color(20, 20, 20, 200);
+ Graphics2D g = src.createGraphics();
+ g.setPaint(Color.RED);
+ g.fillRect(0, 0, 75, 75);
+ g.dispose();
+
+ PText header1 = new PText("Shadow nodes drawn from an image, with increasing blur radius:");
+ getCanvas().getLayer().addChild(header1);
+
+ double x = 25.0d;
+ double y = 25.0d;
+
+ for (int blurRadius = 4; blurRadius < 28; blurRadius += 4) {
+ PImage node = new PImage(src);
+ PShadow shadowNode = new PShadow(src, shadowPaint, blurRadius);
+
+ node.setOffset(x, y);
+ // offset the shadow to account for blur radius offset and light direction
+ shadowNode.setOffset(x - (2 * blurRadius) + 5.0d, y - (2 * blurRadius) + 5.0d);
+
+ // add shadow node before node, or set Z explicitly (e.g. sendToBack())
+ getCanvas().getLayer().addChild(shadowNode);
+ getCanvas().getLayer().addChild(node);
+
+ x += 125.0d;
+ if (x > 300.0d) {
+ y += 125.0d;
+ x = 25.0d;
+ }
+ }
+
+ PText header2 = new PText("Shadow nodes drawn from node.toImage():");
+ header2.setOffset(0.0d, 300.0d);
+ getCanvas().getLayer().addChild(header2);
+
+ PPath rectNode = PPath.createRectangle(0.0f, 0.0f, 75.0f, 75.0f);
+ rectNode.setPaint(Color.RED);
+ rectNode.setStroke(null);
+ rectNode.setOffset(25.0d, 325.0d);
+
+ PShadow rectShadow = new PShadow(rectNode.toImage(), shadowPaint, 8);
+ rectShadow.setOffset(25.0d - (2 * 8) + 5.0d, 325.0d - (2 * 8) + 5.0d);
+
+ getCanvas().getLayer().addChild(rectShadow);
+ getCanvas().getLayer().addChild(rectNode);
+
+ PText textNode = new PText("Shadow Text");
+ textNode.setTextPaint(Color.RED);
+ textNode.setFont(textNode.getFont().deriveFont(36.0f));
+ textNode.setOffset(125.0d, 325.0d);
+
+ PShadow textShadow = new PShadow(textNode.toImage(), shadowPaint, 8);
+ textShadow.setOffset(125.0d - (2 * 8) + 2.5d, 325.0d - (2 * 8) + 2.5d);
+
+ getCanvas().getLayer().addChild(textShadow);
+ getCanvas().getLayer().addChild(textNode);
+ }
+
+ /**
+ * Main.
+ *
+ * @param args command line arguments, ignored
+ */
+ public static void main(final String[] args) {
+ new ShadowExample();
+ }
+}
\ No newline at end of file
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/nodes/PShadow.java b/extras/src/main/java/edu/umd/cs/piccolox/nodes/PShadow.java
new file mode 100755
index 0000000..c6683a0
--- /dev/null
+++ b/extras/src/main/java/edu/umd/cs/piccolox/nodes/PShadow.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2008-2009, 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 edu.umd.cs.piccolox.nodes;
+
+import java.awt.Image;
+import java.awt.Paint;
+
+import java.awt.image.BufferedImage;
+
+import edu.umd.cs.piccolo.nodes.PImage;
+
+import edu.umd.cs.piccolox.util.ShadowUtils;
+
+/**
+ * Shadow node.
+ */
+public final class PShadow extends PImage {
+
+ /**
+ * Create a new shadow node containing a shadow of the specified source image using the
+ * specified shadow paint and gaussian blur radius. The dimensions of this node will be
+ * src.getWidth() + 4 * blurRadius
x src.getHeight() + 4 * blurRadius
+ * to account for blurring beyond the bounds of the source image. Thus the source image
+ * will appear to be be offset by (2 * blurRadius
, 2 * blurRadius
)
+ * in this node.
+ *
+ * @param src source image, must not be null
+ * @param shadowPaint shadow paint
+ * @param blurRadius gaussian blur radius, must be > 0
+ */
+ public PShadow(final Image src, final Paint shadowPaint, final int blurRadius) {
+ super(ShadowUtils.createShadow(src, shadowPaint, blurRadius));
+ }
+}
\ No newline at end of file
diff --git a/extras/src/main/java/edu/umd/cs/piccolox/util/ShadowUtils.java b/extras/src/main/java/edu/umd/cs/piccolox/util/ShadowUtils.java
new file mode 100755
index 0000000..9c67b55
--- /dev/null
+++ b/extras/src/main/java/edu/umd/cs/piccolox/util/ShadowUtils.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2008-2009, 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 edu.umd.cs.piccolox.util;
+
+import java.awt.AlphaComposite;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ConvolveOp;
+import java.awt.image.Kernel;
+
+/**
+ * Static utility methods for creating shadows.
+ */
+public final class ShadowUtils {
+
+ /**
+ * Private no-arg constructor.
+ */
+ private ShadowUtils() {
+ // empty
+ }
+
+
+ /**
+ * Create and return a new buffered image containing a shadow of the specified source image
+ * using the specifed shadow paint and gaussian blur radius. The dimensions of the returned image will be
+ * src.getWidth() + 4 * blurRadius
x src.getHeight() + 4 * blurRadius
+ * to account for blurring beyond the bounds of the source image. Thus the source image
+ * will appear to be be offset by (2 * blurRadius
, 2 * blurRadius
)
+ * in the returned image.
+ *
+ * @param src source image, must not be null
+ * @param shadowPaint shadow paint
+ * @param blurRadius gaussian blur radius, must be > 0
+ * @return a new buffered image containing a shadow of the specified source image
+ * using the specifed shadow paint and gaussian blur radius
+ */
+ public static BufferedImage createShadow(final Image src, final Paint shadowPaint, final int blurRadius) {
+ if (src == null) {
+ throw new IllegalArgumentException("src image must not be null");
+ }
+ if (blurRadius < 1) {
+ throw new IllegalArgumentException("blur radius must be greater than zero, was " + blurRadius);
+ }
+ int w = src.getWidth(null) + (4 * blurRadius);
+ int h = src.getHeight(null) + (4 * blurRadius);
+
+ // paint src image into mask
+ BufferedImage mask = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = mask.createGraphics();
+ g.drawImage(src, 2 * blurRadius, 2 * blurRadius, null);
+
+ // composite mask with shadow paint
+ g.setComposite(AlphaComposite.SrcIn);
+ g.setPaint(shadowPaint);
+ g.fillRect(0, 0, w, h);
+ g.dispose();
+
+ // apply convolve op for blur
+ ConvolveOp convolveOp = new ConvolveOp(new GaussianKernel(blurRadius));
+ BufferedImage shadow = convolveOp.filter(mask, null);
+ return shadow;
+ }
+
+ /**
+ * Gaussian kernel.
+ */
+ private static class GaussianKernel extends Kernel {
+
+ /**
+ * Create a new gaussian kernel with the specified blur radius.
+ *
+ * @param blurRadius blur radius
+ */
+ GaussianKernel(final int blurRadius) {
+ super((2 * blurRadius) + 1, (2 * blurRadius) + 1, createKernel(blurRadius));
+ }
+
+
+ /**
+ * Create an array of floats representing a gaussian kernel with the specified radius.
+ *
+ * @param r radius
+ * @return an array of floats representing a gaussian kernel with the specified radius
+ */
+ private static float[] createKernel(final int r) {
+ int w = (2 * r) + 1;
+ float kernel[] = new float[w * w];
+ double m = 2.0d * Math.pow((r / 3.0d), 2);
+ double n = Math.PI * m;
+
+ double sum = 0.0d;
+ for (int i = 0; i < w; i++) {
+ for (int j = 0; j < w; j++) {
+ kernel[i * w + j] = (float) (Math.pow(Math.E, -((j - r) * (j - r) + (i - r) * (i - r)) / m) / n);
+ sum += kernel[i * w + j];
+ }
+ }
+ for (int i = 0; i < w; i++) {
+ for (int j = 0; j < w; j++) {
+ kernel[i * w + j] /= sum;
+ }
+ }
+ return kernel;
+ }
+ }
+}
\ No newline at end of file
diff --git a/extras/src/test/java/edu/umd/cs/piccolox/nodes/PShadowTest.java b/extras/src/test/java/edu/umd/cs/piccolox/nodes/PShadowTest.java
new file mode 100755
index 0000000..86874f7
--- /dev/null
+++ b/extras/src/test/java/edu/umd/cs/piccolox/nodes/PShadowTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008-2009, 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 edu.umd.cs.piccolox.nodes;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+
+import java.awt.image.BufferedImage;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test for PShadow.
+ */
+public final class PShadowTest extends TestCase {
+
+ public void testConstructor() {
+ BufferedImage src = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
+ Paint srcPaint = new Color(255, 0, 0, 200);
+ Paint shadowPaint = new Color(20, 20, 20, 200);
+ Graphics2D g = src.createGraphics();
+ g.setPaint(srcPaint);
+ g.drawRect(25, 25, 50, 50);
+ g.dispose();
+
+ for (int blurRadius = 1; blurRadius < 33; blurRadius += 4) {
+ PShadow shadowNode = new PShadow(src, shadowPaint, blurRadius);
+ assertNotNull(shadowNode);
+ assertEquals(src.getWidth() + 4 * blurRadius, shadowNode.getWidth(), 0.001d);
+ assertEquals(src.getHeight() + 4 * blurRadius, shadowNode.getHeight(), 0.001d);
+ }
+
+ try {
+ PShadow shadowNode = new PShadow(null, shadowPaint, 4);
+ fail("ctr(null, ...) expected IllegalArgumentException");
+ }
+ catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ PShadow shadowNode = new PShadow(src, shadowPaint, 0);
+ fail("ctr(..., -1) expected IllegalArgumentException");
+ }
+ catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ PShadow shadowNode = new PShadow(src, shadowPaint, -1);
+ fail("ctr(..., -1) expected IllegalArgumentException");
+ }
+ catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
\ No newline at end of file
diff --git a/extras/src/test/java/edu/umd/cs/piccolox/util/ShadowUtilsTest.java b/extras/src/test/java/edu/umd/cs/piccolox/util/ShadowUtilsTest.java
new file mode 100755
index 0000000..5f3139d
--- /dev/null
+++ b/extras/src/test/java/edu/umd/cs/piccolox/util/ShadowUtilsTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008-2009, 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 edu.umd.cs.piccolox.util;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Paint;
+
+import java.awt.image.BufferedImage;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test for ShadowUtils.
+ */
+public final class ShadowUtilsTest extends TestCase {
+
+ public void testCreateShadow() {
+ BufferedImage src = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
+ Paint srcPaint = new Color(255, 0, 0, 200);
+ Paint shadowPaint = new Color(20, 20, 20, 200);
+ Graphics2D g = src.createGraphics();
+ g.setPaint(srcPaint);
+ g.drawRect(25, 25, 50, 50);
+ g.dispose();
+
+ for (int blurRadius = 1; blurRadius < 33; blurRadius += 4) {
+ BufferedImage dest = ShadowUtils.createShadow(src, shadowPaint, blurRadius);
+ assertNotNull(dest);
+ assertEquals(src.getWidth() + 4 * blurRadius, dest.getWidth());
+ assertEquals(src.getHeight() + 4 * blurRadius, dest.getHeight());
+ }
+
+ try {
+ ShadowUtils.createShadow(null, shadowPaint, 4);
+ fail("createShadow(null, ...) expected IllegalArgumentException");
+ }
+ catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ ShadowUtils.createShadow(src, shadowPaint, 0);
+ fail("createShadow(..., 0) expected IllegalArgumentException");
+ }
+ catch (IllegalArgumentException e) {
+ // expected
+ }
+ try {
+ ShadowUtils.createShadow(src, shadowPaint, -1);
+ fail("createShadow(..., -1) expected IllegalArgumentException");
+ }
+ catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+}
\ No newline at end of file