/*
* 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 edu.umd.cs.piccolox.pswing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
import org.piccolo2d.util.PPaintContext;
import junit.framework.TestCase;
public class PSwingTest extends TestCase {
public void setUp() {
RepaintManager.setCurrentManager(new PSwingRepaintManager());
}
public void testConstructorFailsOnNullComponent() {
try {
new PSwing(null);
} catch (final NullPointerException e) {
// expected
}
}
public void testPSwingRegistersItselfWithComponent() {
final JPanel panel = new JPanel();
final PSwing pSwing = new PSwing(panel);
assertEquals(pSwing, panel.getClientProperty(PSwing.PSWING_PROPERTY));
}
public void testGetComponentReturnsValidComponent() {
final JPanel panel = new JPanel();
final PSwing pSwing = new PSwing(panel);
assertEquals(panel, pSwing.getComponent());
}
public void testPSwingResizesItselfWhenComponentIsResized() {
final boolean[] reshaped = new boolean[1];
final JPanel panel = new JPanel();
new PSwing(panel) {
public void updateBounds() {
super.updateBounds();
reshaped[0] = true;
}
};
panel.setSize(100, 100);
assertTrue(reshaped[0]);
}
public void testPSwingDelegatesPaintingToItsComponent() throws IOException {
final JPanel panel = new JPanel();
final MockPaintingPSwing pSwing = new MockPaintingPSwing(panel);
panel.setBackground(Color.RED);
panel.setPreferredSize(new Dimension(100, 100));
final BufferedImage img = pSwing.paintComponent();
assertEquals(Color.RED.getRGB(), img.getRGB(50, 50));
}
public void testHidingPNodeHidesComponent() {
final JPanel panel = new JPanel();
final PSwing pSwing = new PSwing(panel);
pSwing.setVisible(false);
assertFalse(panel.isVisible());
}
public void testAddingSwingComponentToWrappedHierarchyMakesItNotDoubleBuffer() {
final JPanel panel = new JPanel();
final PSwing pSwing = new PSwing(panel);
final JComponent child = new JLabel("Test Component");
child.setDoubleBuffered(true);
panel.add(child);
assertFalse(child.isDoubleBuffered());
}
public void assertDelayedSuccess(String message, int delay, Predicate p) {
int remainingTries = delay / 50;
while (remainingTries > 0) {
if (p.isTrue()) {
return;
}
remainingTries--;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// do nothing
}
}
fail(message);
}
public void assertDelayedSuccess(int delay, Predicate p) {
assertDelayedSuccess("Failed asserting delayed success", delay, p);
}
private interface Predicate {
boolean isTrue();
}
public void testPaintTooSmallPaintsGreek() {
final JPanel panel = new JPanel();
panel.setBounds(0, 0, 100, 100);
final MockPaintingPSwing pSwing = new MockPaintingPSwing(panel);
BufferedImage image = new BufferedImage(100, 100,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
graphics.setTransform(AffineTransform.getScaleInstance(0.01, 0.01));
PPaintContext paintContext = new PPaintContext(graphics);
pSwing.paint(paintContext);
assertTrue(pSwing.isPaintedGreek());
assertFalse(pSwing.isPaintedComponent());
}
public void testPaintBigPaintsComponent() {
final JPanel panel = new JPanel();
panel.setBounds(0, 0, 100, 100);
final MockPaintingPSwing pSwing = new MockPaintingPSwing(panel);
BufferedImage image = new BufferedImage(100, 100,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
graphics.setTransform(AffineTransform.getScaleInstance(5, 5));
PPaintContext paintContext = new PPaintContext(graphics);
pSwing.paint(paintContext);
assertFalse(pSwing.isPaintedGreek());
assertTrue(pSwing.isPaintedComponent());
}
public void testGreekThresholdIsHonoured() {
final JPanel panel = new JPanel();
panel.setBounds(0, 0, 100, 100);
final MockPaintingPSwing pSwing = new MockPaintingPSwing(panel);
pSwing.setGreekThreshold(2);
BufferedImage image = new BufferedImage(100, 100,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
PPaintContext paintContext = new PPaintContext(graphics);
pSwing.paint(paintContext);
assertTrue(pSwing.isPaintedGreek());
assertFalse(pSwing.isPaintedComponent());
}
public void testGreekThresholdIsPersisted() {
final JPanel panel = new JPanel();
final MockPaintingPSwing pSwing = new MockPaintingPSwing(panel);
pSwing.setGreekThreshold(2);
assertEquals(2, pSwing.getGreekThreshold(), Double.MIN_VALUE);
pSwing.setGreekThreshold(0.5);
assertEquals(0.5, pSwing.getGreekThreshold(), Double.MIN_VALUE);
}
public void testAssertSettingJLabelWidthTooSmallGrowsIt() {
final JLabel label = new JLabel("Hello");
PSwingCanvas canvas = new PSwingCanvas();
canvas.setBounds(0, 0, 100, 100);
final MockPaintingPSwing swing = new MockPaintingPSwing(label);
assertDelayedSuccess(500, new Predicate() {
public boolean isTrue() {
return label.getMinimumSize().getWidth() != 0;
}
});
swing.setWidth(10);
canvas.getLayer().addChild(swing);
canvas.doLayout();
// While paint, it uses the graphics element to determine the font's
// display size and hence determine minimum size of JLabel.
swing.paint();
assertFalse(10 == swing.getWidth());
}
public void testAssertSettingJButtonWidthTooSmallGrowsIt() {
JButton label = new JButton("Hello");
PSwingCanvas canvas = new PSwingCanvas();
canvas.setBounds(0, 0, 100, 100);
MockPaintingPSwing swing = new MockPaintingPSwing(label);
assertFalse(label.getMinimumSize().getWidth() == 0);
swing.setWidth(10);
canvas.getLayer().addChild(swing);
canvas.doLayout();
// While paint, it uses the graphics element to determine the font's
// display size and hence determine minimum size of JLabel.
swing.paint();
assertFalse(10 == swing.getWidth());
}
public void testPSwingAttachesItselfToItsCanvasWhenAddedToItsSceneGraph() {
PSwingCanvas canvas1 = new PSwingCanvas();
PSwing label = new PSwing(new JLabel("Hello"));
assertEquals(0, canvas1.getSwingWrapper().getComponentCount());
canvas1.getLayer().addChild(label);
assertEquals(1, canvas1.getSwingWrapper().getComponentCount());
}
public void testPSwingRemovesItselfFromItsCanvasWhenRemovedFromScene() {
PSwingCanvas canvas1 = new PSwingCanvas();
PSwing label = new PSwing(new JLabel("Hello"));
canvas1.getLayer().addChild(label);
assertEquals(1, canvas1.getSwingWrapper().getComponentCount());
label.removeFromParent();
assertEquals(0, canvas1.getSwingWrapper().getComponentCount());
}
public void testPSwingReattachesItselfWhenMovedFromCanvasToCanvas() {
PSwingCanvas canvas1 = new PSwingCanvas();
PSwingCanvas canvas2 = new PSwingCanvas();
PSwing label = new PSwing(new JLabel("Hello"));
canvas1.getLayer().addChild(label);
canvas2.getLayer().addChild(label);
assertEquals(0, canvas1.getSwingWrapper().getComponentCount());
assertEquals(1, canvas2.getSwingWrapper().getComponentCount());
}
public void testPSwingRegistersWithCanvasThroughoutItsLifeCycle() {
PSwingCanvas canvas = new PSwingCanvas();
PSwing label = new PSwing(new JLabel("Hello"));
canvas.getLayer().addChild(label);
assertEquals(1, canvas.getSwingWrapper().getComponentCount());
label.removeFromParent();
assertEquals(0, canvas.getSwingWrapper().getComponentCount());
canvas.getLayer().addChild(label);
assertEquals(1, canvas.getSwingWrapper().getComponentCount());
}
public class MockPaintingPSwing extends PSwing {
private boolean paintedGreek;
private boolean paintedComponent;
public MockPaintingPSwing(JComponent component) {
super(component);
}
public void paintOnto(BufferedImage image) {
PPaintContext paintContext = new PPaintContext(image
.createGraphics());
paint(paintContext);
}
public BufferedImage paint() {
BufferedImage image = new BufferedImage((int) getWidth(),
(int) getHeight(), BufferedImage.TYPE_INT_RGB);
paintOnto(image);
return image;
}
public BufferedImage paintComponent() {
BufferedImage image = new BufferedImage((int) getWidth(),
(int) getHeight(), BufferedImage.TYPE_INT_RGB);
paintComponentOnto(image);
return image;
}
public void paintComponentOnto(BufferedImage image) {
paint(image.createGraphics());
}
public void paint(Graphics2D paintContext) {
super.paint(paintContext);
paintedComponent = true;
}
public void paintAsGreek(Graphics2D paintContext) {
super.paintAsGreek(paintContext);
paintedGreek = true;
}
public boolean isPaintedGreek() {
return paintedGreek;
}
public boolean isPaintedComponent() {
return paintedComponent;
}
}
}