/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2011, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.swing.dialog; import org.geotools.swing.testutils.GraphicsTestBase; import java.awt.image.Raster; import java.awt.image.ColorModel; import java.awt.Dimension; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; import java.awt.image.BufferedImage; import java.util.concurrent.CountDownLatch; import javax.swing.JFrame; import javax.swing.JLabel; import org.geotools.swing.testutils.TestImageFrame; import org.geotools.swing.testutils.GraphicsTestRunner; import org.fest.swing.edt.GuiActionRunner; import org.fest.swing.edt.GuiQuery; import org.fest.swing.fixture.FrameFixture; import org.fest.swing.fixture.JLabelFixture; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; /** * Tests for the DialogUtils class. * * @author Michael Bedward * @since 8.0 * @source $URL$ * @version $Id$ */ @RunWith(GraphicsTestRunner.class) public class DialogUtilsTest extends GraphicsTestBase { /** * Set this to true to display the screen shot image of the label * in the test {@linkplain #labelTextIsFittedProperly()}. */ private static final boolean displayLabelImage = false; @Test public void labelTextExtentCanBeCalledSafelyOutsideEDT() { // Just testing there is no exception Dimension dim = DialogUtils.getHtmlLabelTextExtent("foo", 300, true); } /** * Tests display of a long html text string in a label. The string includes a * red dot and the start and a blue dot at the end. When the label is rendered * we grab a screen shot and then search for the dots to check that the whole of * the text string was visible. * <p> * TODO: It would also be good to have a way of checking that the label does not * include too much slack space. */ @Test public void labelTextIsFittedProperly() throws Exception { final StringBuilder sb = new StringBuilder(); sb.append("<html>"); // Red dot at start of text sb.append("<span style=\"color: #FF0000;\">.</span>"); // Long text sb.append("This is a very very very very very very very very very very "); sb.append("very very very very very very very very very very very very "); sb.append("very very very very very very very very very very very very "); sb.append("long message"); // Blue dot at end of text sb.append("<span style=\"color: #0000FF;\">.</span>"); sb.append("</html>"); final int labelWidth = 300; final Dimension dim = DialogUtils.getHtmlLabelTextExtent(sb.toString(), labelWidth, true); JFrame frame = GuiActionRunner.execute(new GuiQuery<JFrame>() { @Override protected JFrame executeInEDT() throws Throwable { JFrame frame = new JFrame(); /** * mbedward: * I tried overriding the label's paintComponent method to * disable text anti-aliasing in order to make searching for * the red and blue dots easier, but the rendering hint did * not seem to affect HTML rendering. So instead, the * findColorInRange method is used to allow for the fuzz of * colour values. */ JLabel label = new JLabel(sb.toString()); label.setName("TheLabel"); label.setPreferredSize(dim); frame.add(label); frame.pack(); return frame; } }); FrameFixture fixture = new FrameFixture(frame); Insets insets = frame.getInsets(); fixture.show(); JLabelFixture lf = fixture.label("TheLabel"); Point pos = lf.component().getLocationOnScreen(); Dimension size = lf.component().getSize(); Robot robot = new Robot(); BufferedImage img = robot.createScreenCapture(new Rectangle(pos, dim)); fixture.close(); if (displayLabelImage) { CountDownLatch latch = TestImageFrame.showImage(img, "Label screen shot"); latch.await(); } // Search for the red-ish start dot int[] lower = new int[] {200, 0, 0}; int[] upper = new int[] {255, 80, 80}; Rectangle bounds = new Rectangle(img.getMinX(), img.getMinY(), 20, 20); assertTrue( findColorInRange(img, bounds, lower, upper) ); // Search for the blue-ish end dot lower = new int[] {0, 0, 200}; upper = new int[] {80, 80, 255}; bounds = new Rectangle( img.getMinX(), img.getMinY() + img.getHeight() - 20, img.getWidth(), 20); assertTrue( findColorInRange(img, bounds, lower, upper)); fixture.cleanUp(); } private boolean findColorInRange(BufferedImage img, Rectangle bounds, int[] lowerRGB, int[] upperRGB) { final Raster raster = img.getData(); final ColorModel cm = img.getColorModel(); boolean found = false; for (int y = bounds.y, ny = 0; ny < bounds.height; y++, ny++) { for (int x = bounds.x, nx = 0; nx < bounds.width; x++, nx++) { int sample = img.getRGB(x, y); int red = cm.getRed(sample); int green = cm.getGreen(sample); int blue = cm.getBlue(sample); if (red >= lowerRGB[0] && red <= upperRGB[0] && green >= lowerRGB[1] && green <= upperRGB[1] && blue >= lowerRGB[2] && blue <= upperRGB[2]) { found = true; break; } } } return found; } }