diff --git a/openide.explorer/src/org/openide/explorer/view/VisualizerNode.java b/openide.explorer/src/org/openide/explorer/view/VisualizerNode.java --- a/openide.explorer/src/org/openide/explorer/view/VisualizerNode.java +++ b/openide.explorer/src/org/openide/explorer/view/VisualizerNode.java @@ -56,10 +56,10 @@ import java.util.*; import javax.swing.Icon; -import javax.swing.ImageIcon; import javax.swing.SwingUtilities; import javax.swing.event.EventListenerList; import javax.swing.tree.TreeNode; +import org.openide.util.ImageUtilities; /** Visual representation of one node. Holds necessary information about nodes @@ -206,7 +206,14 @@ if (desc == UNKNOWN) { shortDescription = desc = node.getShortDescription(); } - + if (icon instanceof Image) { + String toolTip = ImageUtilities.getImageToolTip((Image) icon); + if (toolTip.length() > 0) { + StringBuilder str = new StringBuilder(128); + str.append("").append(desc).append("
").append(toolTip).append(""); + desc = str.toString(); + } + } return desc; } @@ -407,7 +414,7 @@ if (Node.PROP_NAME.equals(name) || Node.PROP_DISPLAY_NAME.equals(name) || isIconChange) { if (isIconChange) { //Ditch the cached icon type so the next call to getIcon() will - //recreate the ImageIcon + //recreate the Icon cachedIconType = -1; } @@ -558,7 +565,7 @@ icon = getDefaultIcon(); } else { - icon = new ImageIcon(image); + icon = ImageUtilities.image2Icon(image); } } @@ -577,9 +584,8 @@ /** Loads default icon if not loaded. */ private static Icon getDefaultIcon() { if (defaultIcon == null) { - defaultIcon = new ImageIcon(Utilities.loadImage(DEFAULT_ICON)); + defaultIcon = ImageUtilities.image2Icon(ImageUtilities.loadImage(DEFAULT_ICON)); } - return defaultIcon; } diff --git a/openide.explorer/test/unit/src/org/openide/explorer/view/VisualizerNodeTest.java b/openide.explorer/test/unit/src/org/openide/explorer/view/VisualizerNodeTest.java --- a/openide.explorer/test/unit/src/org/openide/explorer/view/VisualizerNodeTest.java +++ b/openide.explorer/test/unit/src/org/openide/explorer/view/VisualizerNodeTest.java @@ -89,4 +89,16 @@ assertEquals("Index is 1", 1, ta.getIndex(tm)); } + + public void testIconsAreShared() { + AbstractNode a1 = new AbstractNode(Children.LEAF); + VisualizerNode v1 = VisualizerNode.getVisualizer(null, a1); + Icon icon1 = v1.getIcon(false, false); + + AbstractNode a2 = new AbstractNode(Children.LEAF); + VisualizerNode v2 = VisualizerNode.getVisualizer(null, a2); + Icon icon2 = v2.getIcon(false, false); + + assertSame("Icon instances should be same", icon1, icon2); + } } diff --git a/openide.util/apichanges.xml b/openide.util/apichanges.xml --- a/openide.util/apichanges.xml +++ b/openide.util/apichanges.xml @@ -49,6 +49,41 @@ Actions API + + + Image methods were made deprecated in Utilities, replacement is + ImageUtilities class (with additional methods). + + + + + +

+ Image methods were made deprecated in Utilities. Replacement is + ImageUtilities + (renamed IconManager). It contains also new + methods for image tool tips manipulation: + New methods for tool tips manipulation: + Image assignToolTipToImage(Image image, String text); + String getImageToolTip(Image image); + Image addToolTipToImage(Image image, String text); +

+

+ New method for conversion from Image to Icon: + Icon image2Icon(Image image); +

+

+ Deprecated methods in Utilities: + Image icon2Image(Icon icon); + Image loadImage(String resourceID); + Image loadImage(String resource, boolean localized); + Image mergeImages(Image image1, Image image2, int x, int y); +

+
+ + + +
Mutex made pluggable diff --git a/openide.util/nbproject/project.properties b/openide.util/nbproject/project.properties --- a/openide.util/nbproject/project.properties +++ b/openide.util/nbproject/project.properties @@ -41,7 +41,7 @@ javac.source=1.5 module.jar.dir=lib -spec.version.base=7.13.0 +spec.version.base=7.14.0 # For XMLSerializer, needed for XMLUtil.write to work w/ namespaces under JDK 1.4: diff --git a/openide.util/src/org/openide/util/IconManager.java b/openide.util/src/org/openide/util/ImageUtilities.java rename from openide.util/src/org/openide/util/IconManager.java rename to openide.util/src/org/openide/util/ImageUtilities.java --- a/openide.util/src/org/openide/util/IconManager.java +++ b/openide.util/src/org/openide/util/ImageUtilities.java @@ -42,6 +42,7 @@ package org.openide.util; import java.awt.Component; +import java.awt.Graphics; import java.awt.HeadlessException; import java.awt.Image; import java.awt.MediaTracker; @@ -50,10 +51,13 @@ import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; +import java.awt.image.IndexColorModel; +import java.awt.image.WritableRaster; import java.io.IOException; import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.HashSet; +import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -63,18 +67,26 @@ import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JLabel; -/** Registers all loaded images into the AbstractNode, so nothing is loaded twice. -* -* @author Jaroslav Tulach -*/ -final class IconManager extends Object { +/** + * Useful static methods for manipulation with images/icons, results are cached. + * + * @author Jaroslav Tulach, Tomas Holy + * @since 7.14 + */ +public final class ImageUtilities { + /** separator for individual parts of tool tip text */ + static final String TOOLTIP_SEPAR = "
"; // NOI18N /** a value that indicates that the icon does not exists */ private static final ActiveRef NO_ICON = new ActiveRef(null, null, null); private static final Map> cache = new HashMap>(128); private static final Map> localizedCache = new HashMap>(128); private static final Map> compositeCache = new HashMap>(128); + private static final Map> imageToolTipCache = new HashMap>(128); /** Resource paths for which we have had to strip initial slash. * @see "#20072" @@ -84,7 +96,7 @@ private static Lookup.Result loaderQuery = null; private static boolean noLoaderWarned = false; private static final Component component = new Component() { - }; + }; private static final MediaTracker tracker = new MediaTracker(component); private static int mediaTrackerID; @@ -92,13 +104,161 @@ private static ImageReader PNG_READER; // private static ImageReader GIF_READER; - private static final Logger ERR = Logger.getLogger(IconManager.class.getName()); + private static final Logger ERR = Logger.getLogger(ImageUtilities.class.getName()); + + private ImageUtilities() { + } static { ImageIO.setUseCache(false); PNG_READER = ImageIO.getImageReadersByMIMEType("image/png").next(); // GIF_READER = ImageIO.getImageReadersByMIMEType("image/gif").next(); } + + /** + * Loads an image from the specified resource ID. The image is loaded using the "system" classloader registered in + * Lookup. + * @param resourceID resource path of the icon (no initial slash) + * @return icon's Image, or null, if the icon cannot be loaded. + */ + public static final Image loadImage(String resourceID) { + return getIcon(resourceID, false); + } + + /** + * Loads an image based on resource path. + * Exactly like {@link #loadImage(String)} but may do a localized search. + * For example, requesting org/netbeans/modules/foo/resources/foo.gif + * might actually find org/netbeans/modules/foo/resources/foo_ja.gif + * or org/netbeans/modules/foo/resources/foo_mybranding.gif. + * + *

Caching of loaded images can be used internally to improve performance. + * + */ + public static final Image loadImage(String resource, boolean localized) { + return getIcon(resource, localized); + } + + /** This method merges two images into the new one. The second image is drawn + * over the first one with its top-left corner at x, y. Images need not be of the same size. + * New image will have a size of max(second image size + top-left corner, first image size). + * Method is used mostly when second image contains transparent pixels (e.g. for badging). + * Method that attempts to find the merged image in the cache first, then + * creates the image if it was not found. + * @param image1 underlying image + * @param image2 second image + * @param x x position of top-left corner + * @param y y position of top-left corner + * @return new merged image + */ + public static final Image mergeImages(Image image1, Image image2, int x, int y) { + if (image1 == null || image2 == null) { + throw new NullPointerException(); + } + + CompositeImageKey k = new CompositeImageKey(image1, image2, x, y); + Image cached; + + synchronized (compositeCache) { + ActiveRef r = compositeCache.get(k); + if (r != null) { + cached = r.get(); + if (cached != null) { + return cached; + } + } + cached = doMergeImages(image1, image2, x, y); + compositeCache.put(k, new ActiveRef(cached, compositeCache, k)); + return cached; + } + } + + /** + * Converts given image to a {@link javax.swing.Icon}. + * @param image {@link java.awt.Image} to be converted. + * @return icon corresponding {@link javax.swing.Icon} + */ + public static final Icon image2Icon(Image image) { + if (image instanceof ToolTipImage) { + return (Icon) image; + } else { + return new ImageIcon(image); + } + } + + /** + * Converts given icon to a {@link java.awt.Image}. + * + * @param icon {@link javax.swing.Icon} to be converted. + */ + public static final Image icon2Image(Icon icon) { + if (icon instanceof ToolTipImage) { + return (Image) icon; + } else { + ToolTipImage image = new ToolTipImage("", icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics g = image.getGraphics(); + icon.paintIcon(new JLabel(), g, 0, 0); + g.dispose(); + return image; + } + } + + /** + * Assign tool tip text to given image (creates new or returns cached, original remains unmodified) + * Text can contain HTML tags e.g. "<b>my</b> text" + * @param image image to which tool tip should be set + * @param text tool tip text + * @return Image with attached tool tip + */ + public static final Image assignToolTipToImage(Image image, String text) { + ToolTipImageKey key = new ToolTipImageKey(image, text); + Image cached; + synchronized (imageToolTipCache) { + ActiveRef r = imageToolTipCache.get(key); + if (r != null) { + cached = r.get(); + if (cached != null) { + return cached; + } + } + cached = ToolTipImage.createNew(text, image); + imageToolTipCache.put(key, new ActiveRef(cached, imageToolTipCache, key)); + return cached; + } + } + + /** + * Get tool tip text for given image + * @param image image which is asked for tool tip text + * @return String containing attached tool tip text + */ + public static final String getImageToolTip(Image image) { + if (image instanceof ToolTipImage) { + return ((ToolTipImage) image).toolTipText; + } else { + return ""; + } + } + + /** + * Add text to tool tip for given image (creates new or returns cached, original remains unmodified) + * Text can contain HTML tags e.g. "<b>my</b> text" + * @param text text to add to tool tip + * @return Image with attached tool tip + */ + public static final Image addToolTipToImage(Image image, String text) { + if (image instanceof ToolTipImage) { + ToolTipImage tti = (ToolTipImage) image; + StringBuilder str = new StringBuilder(tti.toolTipText); + if (str.length() > 0 && text.length() > 0) { + str.append(TOOLTIP_SEPAR); + } + str.append(text); + return assignToolTipToImage(image, str.toString()); + } else { + return assignToolTipToImage(image, text); + } + } /** * Get the class loader from lookup. @@ -184,7 +344,7 @@ // #31008. [PENDING] remove in case package cache is precomputed java.net.URL baseurl = (loader != null) ? loader.getResource(resource) // NOPMD - : IconManager.class.getClassLoader().getResource(resource); + : ImageUtilities.class.getClassLoader().getResource(resource); Iterator it = NbBundle.getLocalizingSuffixes(); while (it.hasNext()) { @@ -199,13 +359,10 @@ if (i != null) { localizedCache.put(resource, new ActiveRef(i, localizedCache, resource)); - return i; } } - localizedCache.put(resource, NO_ICON); - return null; } } else { @@ -270,7 +427,7 @@ // we have to load it java.net.URL url = (loader != null) ? loader.getResource(n) - : IconManager.class.getClassLoader().getResource(n); + : ImageUtilities.class.getClassLoader().getResource(n); // img = (url == null) ? null : Toolkit.getDefaultToolkit().createImage(url); Image result = null; @@ -321,47 +478,17 @@ // Image img2 = toBufferedImage(result); - ERR.log(Level.FINE, - "loading icon {0} = {1}", new Object[] {n, result}); + ERR.log(Level.FINE, "loading icon {0} = {1}", new Object[] {n, result}); name = new String(name).intern(); // NOPMD - + result = ToolTipImage.createNew("", result); cache.put(name, new ActiveRef(result, cache, name)); - return result; } else { // no icon found - if (!localizedQuery) { cache.put(name, NO_ICON); } - return null; } - } - } - - /** - * Method that attempts to find the merged image in the cache first, then - * creates the image if it was not found. - */ - static final Image mergeImages(Image im1, Image im2, int x, int y) { - CompositeImageKey k = new CompositeImageKey(im1, im2, x, y); - Image cached; - - synchronized (compositeCache) { - ActiveRef r = compositeCache.get(k); - - if (r != null) { - cached = r.get(); - - if (cached != null) { - return cached; - } - } - - cached = doMergeImages(im1, im2, x, y); - compositeCache.put(k, new ActiveRef(cached, compositeCache, k)); - - return cached; } } @@ -394,7 +521,6 @@ synchronized (tracker) { int id = ++mediaTrackerID; - tracker.addImage(image, id); try { @@ -407,7 +533,7 @@ tracker.removeImage(image, id); } } - + private static final Image doMergeImages(Image image1, Image image2, int x, int y) { ensureLoaded(image1); ensureLoaded(image2); @@ -417,8 +543,17 @@ boolean bitmask = (image1 instanceof Transparency) && ((Transparency)image1).getTransparency() != Transparency.TRANSLUCENT && (image2 instanceof Transparency) && ((Transparency)image2).getTransparency() != Transparency.TRANSLUCENT; + StringBuilder str = new StringBuilder(image1 instanceof ToolTipImage ? ((ToolTipImage)image1).toolTipText : ""); + if (image2 instanceof ToolTipImage) { + String toolTip = ((ToolTipImage)image2).toolTipText; + if (str.length() > 0 && toolTip.length() > 0) { + str.append(TOOLTIP_SEPAR); + } + str.append(toolTip); + } + ColorModel model = colorModel(bitmask? Transparency.BITMASK: Transparency.TRANSLUCENT); - java.awt.image.BufferedImage buffImage = new java.awt.image.BufferedImage( + ToolTipImage buffImage = new ToolTipImage(str.toString(), model, model.createCompatibleWritableRaster(w, h), model.isAlphaPremultiplied(), null ); @@ -454,7 +589,6 @@ catch(HeadlessException he) { model = ColorModel.getRGBdefault(); } - return model; } @@ -474,6 +608,7 @@ this.overlayImage = overlay; } + @Override public boolean equals(Object other) { if (!(other instanceof CompositeImageKey)) { return false; @@ -484,6 +619,7 @@ return (x == k.x) && (y == k.y) && (baseImage == k.baseImage) && (overlayImage == k.overlayImage); } + @Override public int hashCode() { int hash = ((x << 3) ^ y) << 4; hash = hash ^ baseImage.hashCode() ^ overlayImage.hashCode(); @@ -491,8 +627,42 @@ return hash; } + @Override public String toString() { return "Composite key for " + baseImage + " + " + overlayImage + " at [" + x + ", " + y + "]"; // NOI18N + } + } + + /** + * Key used for ToolTippedImage + */ + private static class ToolTipImageKey { + Image image; + String str; + + ToolTipImageKey(Image image, String str) { + this.image = image; + this.str = str; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof ToolTipImageKey)) { + return false; + } + ToolTipImageKey k = (ToolTipImageKey) other; + return (str.equals(k.str)) && (image == k.image); + } + + @Override + public int hashCode() { + int hash = image.hashCode() ^ str.hashCode(); + return hash; + } + + @Override + public String toString() { + return "ImageStringKey for " + image + " + " + str; // NOI18N } } @@ -514,4 +684,58 @@ } } // end of ActiveRef + + /** + * Image with tool tip text (for icons with badges) + */ + private static class ToolTipImage extends BufferedImage implements Icon { + final String toolTipText; + + public static ToolTipImage createNew(String toolTipText, Image image) { + ImageUtilities.ensureLoaded(image); + boolean bitmask = (image instanceof Transparency) && ((Transparency) image).getTransparency() != Transparency.TRANSLUCENT; + ColorModel model = colorModel(bitmask ? Transparency.BITMASK : Transparency.TRANSLUCENT); + int w = image.getWidth(null); + int h = image.getHeight(null); + ToolTipImage newImage = new ToolTipImage(toolTipText, model, model.createCompatibleWritableRaster(w, h), model.isAlphaPremultiplied(), null); + + java.awt.Graphics g = newImage.createGraphics(); + g.drawImage(image, 0, 0, null); + g.dispose(); + return newImage; + } + + public ToolTipImage(String toolTipText, ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable properties) { + super(cm, raster, isRasterPremultiplied, properties); + this.toolTipText = toolTipText; + } + + public ToolTipImage(String toolTipText, int width, int height, int imageType, IndexColorModel cm) { + super(width, height, imageType, cm); + this.toolTipText = toolTipText; + } + + public ToolTipImage(String toolTipText, int width, int height, int imageType) { + super(width, height, imageType); + this.toolTipText = toolTipText; + } + + public ToolTipImage(String toolTipText, BufferedImage image) { + super(image.getWidth(), image.getHeight(), image.getType()); + this.toolTipText = toolTipText; + } + + + public int getIconHeight() { + return super.getHeight(); + } + + public int getIconWidth() { + return super.getWidth(); + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + g.drawImage(this, x, y, null); + } + } } diff --git a/openide.util/src/org/openide/util/Utilities.java b/openide.util/src/org/openide/util/Utilities.java --- a/openide.util/src/org/openide/util/Utilities.java +++ b/openide.util/src/org/openide/util/Utilities.java @@ -48,7 +48,6 @@ import java.awt.Dialog; import java.awt.Dimension; import java.awt.Frame; -import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.Image; @@ -61,7 +60,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; -import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -99,8 +97,6 @@ import java.util.logging.Logger; import javax.swing.Action; import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JSeparator; @@ -2588,33 +2584,28 @@ * over the first one with its top-left corner at x, y. Images need not be of the same size. * New image will have a size of max(second image size + top-left corner, first image size). * Method is used mostly when second image contains transparent pixels (e.g. for badging). - * If both images are null, it makes default transparent 16x16 image. * @param image1 underlying image * @param image2 second image * @param x x position of top-left corner * @param y y position of top-left corner * @return new merged image + * @deprecated Use {@link ImageUtilities#mergeImages}. */ + @Deprecated public static final Image mergeImages(Image image1, Image image2, int x, int y) { - if (image1 == null) { - throw new NullPointerException(); - } - - if (image2 == null) { - throw new NullPointerException(); - } - - return IconManager.mergeImages(image1, image2, x, y); + return ImageUtilities.mergeImages(image1, image2, x, y); } - + /** * Loads an image from the specified resource ID. The image is loaded using the "system" classloader registered in * Lookup. * @param resourceID resource path of the icon (no initial slash) * @return icon's Image, or null, if the icon cannot be loaded. + * @deprecated Use {@link ImageUtilities#loadImage(java.lang.String)}. */ + @Deprecated public static final Image loadImage(String resourceID) { - return IconManager.getIcon(resourceID, false); + return ImageUtilities.loadImage(resourceID); } /** @@ -2622,17 +2613,11 @@ * * @param icon {@link javax.swing.Icon} to be converted. * @since 7.3 + * @deprecated Use {@link ImageUtilities#icon2Image}. */ + @Deprecated public static final Image icon2Image(Icon icon) { - if (icon instanceof ImageIcon) { - return ((ImageIcon) icon).getImage(); - } else { - BufferedImage bImage = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics g = bImage.getGraphics(); - icon.paintIcon(new JLabel(), g, 0, 0); - g.dispose(); - return bImage; - } + return ImageUtilities.icon2Image(icon); } /** Builds a popup menu from actions for provided context specified by @@ -2796,9 +2781,11 @@ *

Caching of loaded images can be used internally to improve performance. * * @since 3.24 + * @deprecated Use {@link ImageUtilities#loadImage(java.lang.String, boolean)}. */ + @Deprecated public static final Image loadImage(String resource, boolean localized) { - return IconManager.getIcon(resource, localized); + return ImageUtilities.loadImage(resource, localized); } /** @@ -2865,7 +2852,7 @@ } // need to resize the icon - Image empty = IconManager.createBufferedImage(d.width, d.height); + Image empty = ImageUtilities.createBufferedImage(d.width, d.height); i = Utilities.mergeImages(icon, empty, 0, 0); } @@ -3038,14 +3025,17 @@ this.deprecated = deprecated; } + @Override public Reference poll() { throw new UnsupportedOperationException(); } + @Override public Reference remove(long timeout) throws IllegalArgumentException, InterruptedException { throw new InterruptedException(); } + @Override public Reference remove() throws InterruptedException { throw new InterruptedException(); } diff --git a/openide.util/test/unit/src/org/openide/util/IconManagerGetLoaderTest.java b/openide.util/test/unit/src/org/openide/util/ImageUtilitiesGetLoaderTest.java rename from openide.util/test/unit/src/org/openide/util/IconManagerGetLoaderTest.java rename to openide.util/test/unit/src/org/openide/util/ImageUtilitiesGetLoaderTest.java --- a/openide.util/test/unit/src/org/openide/util/IconManagerGetLoaderTest.java +++ b/openide.util/test/unit/src/org/openide/util/ImageUtilitiesGetLoaderTest.java @@ -54,9 +54,9 @@ * * @author Jaroslav Tulach */ -public class IconManagerGetLoaderTest extends TestCase { +public class ImageUtilitiesGetLoaderTest extends TestCase { static { - System.setProperty("org.openide.util.Lookup", "org.openide.util.IconManagerGetLoaderTest$Lkp"); + System.setProperty("org.openide.util.Lookup", "org.openide.util.ImageUtilitiesGetLoaderTest$Lkp"); Logger l = Logger.getLogger(""); @@ -69,28 +69,30 @@ } - public IconManagerGetLoaderTest (String testName) { + public ImageUtilitiesGetLoaderTest (String testName) { super (testName); } + @Override protected void setUp () throws Exception { } + @Override protected void tearDown () throws Exception { } public static Test suite () { - TestSuite suite = new TestSuite(IconManagerGetLoaderTest.class); + TestSuite suite = new TestSuite(ImageUtilitiesGetLoaderTest.class); return suite; } public void testWrongImplOfGetLoaderIssue62194() throws Exception { - ClassLoader l = IconManager.getLoader (); + ClassLoader l = ImageUtilities.getLoader (); assertTrue("Error manager race condition activated", ErrMgr.switchDone); assertEquals("c1 the original one", Lkp.c1, l); - ClassLoader n = IconManager.getLoader (); + ClassLoader n = ImageUtilities.getLoader (); assertEquals("c2 the new one", Lkp.c2, n); } diff --git a/openide.util/test/unit/src/org/openide/util/IconManagerTest.java b/openide.util/test/unit/src/org/openide/util/ImageUtilitiesTest.java rename from openide.util/test/unit/src/org/openide/util/IconManagerTest.java rename to openide.util/test/unit/src/org/openide/util/ImageUtilitiesTest.java --- a/openide.util/test/unit/src/org/openide/util/IconManagerTest.java +++ b/openide.util/test/unit/src/org/openide/util/ImageUtilitiesTest.java @@ -44,17 +44,16 @@ import java.awt.Image; import java.awt.Transparency; import java.awt.image.BufferedImage; +import javax.swing.Icon; import junit.framework.*; -import java.lang.ref.*; -import java.util.*; /** * * @author Radim Kubacki */ -public class IconManagerTest extends TestCase { +public class ImageUtilitiesTest extends TestCase { - public IconManagerTest (String testName) { + public ImageUtilitiesTest (String testName) { super (testName); } @@ -76,7 +75,7 @@ g.fillRect(0, 0, 2, 2); g.dispose(); - Image mergedImg = IconManager.mergeImages(img1, img2, 0, 0); + Image mergedImg = ImageUtilities.mergeImages(img1, img2, 0, 0); if (!(mergedImg instanceof BufferedImage)) { fail("It is assumed that mergeImages returns BufferedImage. Need to update test"); } @@ -102,7 +101,7 @@ g.fillRect(0, 0, 2, 2); g.dispose(); - Image mergedImg = IconManager.mergeImages(img1, img2, 0, 0); + Image mergedImg = ImageUtilities.mergeImages(img1, img2, 0, 0); if (!(mergedImg instanceof BufferedImage)) { fail("It is assumed that mergeImages returns BufferedImage. Need to update test"); } @@ -112,5 +111,68 @@ assertEquals(Color.RED, new Color(merged.getRGB(1, 1))); assertEquals(Color.BLUE, new Color(merged.getRGB(10, 10))); } - + + public void testImageToolTip() { + BufferedImage img1 = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB); + java.awt.Graphics2D g = img1.createGraphics(); + g.setColor(Color.BLUE); + g.fillRect(0, 0, 16, 16); + g.dispose(); + + assertEquals("Tool tip text should be empty", "", ImageUtilities.getImageToolTip(img1)); + + String text = "test"; + Image imgTT1 = ImageUtilities.assignToolTipToImage(img1, text); + assertEquals("Should remain empty", "", ImageUtilities.getImageToolTip(img1)); + String str = ImageUtilities.getImageToolTip(imgTT1); + assertEquals("We should get what we set", text, str); + + Image imgTT2 = ImageUtilities.assignToolTipToImage(img1, "test"); + assertSame("Instances should be same", imgTT1, imgTT2); + + imgTT2 = ImageUtilities.addToolTipToImage(img1, ""); + imgTT2 = ImageUtilities.addToolTipToImage(imgTT2, "test"); + str = ImageUtilities.getImageToolTip(imgTT2); + String expected = "test"; + assertEquals("Tool tip text should be: " + expected + ", but it is " + str, expected, str); + + imgTT2 = ImageUtilities.addToolTipToImage(imgTT1, "test2"); + str = ImageUtilities.getImageToolTip(imgTT2); + expected = "test" + ImageUtilities.TOOLTIP_SEPAR + "test2"; + assertEquals("Tool tip text should be: " + expected + ", but it is " + str, expected, str); + + BufferedImage img2 = new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB); + g = img2.createGraphics(); + g.setColor(Color.RED); + g.fillRect(0, 0, 2, 2); + g.dispose(); + + imgTT1 = ImageUtilities.assignToolTipToImage(img1, "Tool tip image1"); + imgTT2 = ImageUtilities.assignToolTipToImage(img2, "Tool tip image2"); + Image result = ImageUtilities.mergeImages(imgTT1, imgTT2, 0, 0); + expected = "Tool tip image1" + ImageUtilities.TOOLTIP_SEPAR + "Tool tip image2"; + str = ImageUtilities.getImageToolTip(result); + assertEquals("Tool tip text should be: " + expected + ", but it is " + str, expected, str); + + result = ImageUtilities.mergeImages(imgTT1, img2, 0, 0); + str = ImageUtilities.getImageToolTip(result); + expected = "Tool tip image1"; + assertEquals("Tool tip text should be: " + expected + ", but it is " + str, expected, str); + + result = ImageUtilities.mergeImages(img1, imgTT2, 0, 0); + str = ImageUtilities.getImageToolTip(result); + expected = "Tool tip image2"; + assertEquals("Tool tip text should be: " + expected + ", but it is " + str, expected, str); + + result = ImageUtilities.mergeImages(img1, img2, 0, 0); + str = ImageUtilities.getImageToolTip(result); + expected = ""; + assertEquals("Tool tip text should be empty, but it is " + str, expected, str); + + Icon icon = ImageUtilities.image2Icon(result); + assertSame("Should be same instance", icon, result); + + Image img = ImageUtilities.icon2Image(icon); + assertSame("Should be same instance", icon, img); + } }