package com.revolsys.swing; import java.awt.Cursor; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.imageio.ImageIO; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.UIDefaults; import javax.swing.UIManager; import com.revolsys.awt.WebColors; import com.revolsys.util.IconNameProxy; import com.revolsys.util.OS; import com.revolsys.util.Property; public class Icons { public static final String BADGE_FOLDER = "/com/revolsys/famfamfam/silk/badges/"; private static final Map<Icon, Icon> DISABLED_ICON_BY_ICON = new HashMap<>(); private static final Map<String, Icon> DISABLED_ICON_CACHE = new HashMap<>(); private static final Map<Image, BufferedImage> DISABLED_IMAGE_CACHE = new HashMap<>(); private static final Map<String, Icon> ICON_CACHE = new HashMap<>(); private static final Map<String, Reference<BufferedImage>> NAMED_DISABLED_IMAGE_CACHE = new HashMap<>(); private static final Map<String, Reference<BufferedImage>> NAMED_IMAGE_CACHE = new HashMap<>(); public static final String RESOURCE_FOLDER = "/com/revolsys/famfamfam/silk/icons/"; public static void addIcon(final List<Icon> icons, Icon icon, final boolean enabled) { if (icon != null) { if (!enabled) { icon = Icons.getDisabledIcon(icon); } icons.add(icon); } } public static BufferedImage alpha(final Image image, final float percent) { BufferedImage bufferedImage; final int width = image.getWidth(null); final int height = image.getHeight(null); if (image instanceof BufferedImage) { bufferedImage = (BufferedImage)image; } else { bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); final Graphics2D graphics = bufferedImage.createGraphics(); graphics.drawImage(image, 0, 0, null); graphics.dispose(); } final BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); final int[] avgLUT = new int[766]; for (int i = 0; i < avgLUT.length; i++) { avgLUT[i] = i / 3; } for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { final int rgb = bufferedImage.getRGB(i, j); final int alpha = rgb >> 24 & 0xff; final int red = rgb >> 16 & 0xff; final int green = rgb >> 8 & 0xff; final int blue = rgb & 0xff; final int newAlpha = (int)Math.ceil(alpha * percent); final int newRgb = WebColors.colorToRGB(newAlpha, red, green, blue); newImage.setRGB(i, j, newRgb); } } return newImage; } public static ImageIcon getAnimatedIcon(final String imageFileName) { final Class<?> clazz = Icons.class; final String resourceName = RESOURCE_FOLDER + imageFileName; URL url = clazz.getResource(resourceName); if (url == null) { final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); url = classLoader.getResource("images/" + imageFileName); if (url == null) { url = classLoader.getResource("icons/" + imageFileName); } } return new ImageIcon(url); } public static BufferedImage getBadgeImage(final String imageName) { final String resourceName = BADGE_FOLDER + imageName + ".png"; final InputStream in = Icons.class.getResourceAsStream(resourceName); return getImage(in); } public static Cursor getCursor(final String imageName) { return getCursor(imageName, 0, 0); } public static Cursor getCursor(final String imageName, final int delta) { return getCursor(imageName, delta, delta); } public static Cursor getCursor(final String imageName, final int dx, final int dy) { Image image = getImage(imageName); if (image == null) { return null; } else { final Toolkit toolkit = Toolkit.getDefaultToolkit(); if (OS.isWindows()) { final BufferedImage newImage = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB); final Graphics graphics = newImage.getGraphics(); graphics.drawImage(image, 0, 0, null); graphics.dispose(); image = newImage; } return toolkit.createCustomCursor(image, new Point(dx, dy), imageName); } } public static Icon getDisabledIcon(final Icon icon) { if (icon == null) { return null; } else { Icon disabledIcon = DISABLED_ICON_BY_ICON.get(icon); if (disabledIcon == null) { if (icon instanceof ImageIcon) { final ImageIcon imageIcon = (ImageIcon)icon; final String imageName = imageIcon.getDescription(); if (imageName != null) { disabledIcon = getDisabledIcon(imageName); } if (disabledIcon == null) { final Image image = imageIcon.getImage(); final BufferedImage disabledImage = getDisabledImage(image); disabledIcon = new ImageIcon(disabledImage); DISABLED_ICON_BY_ICON.put(icon, disabledIcon); } } else { return icon; } } return disabledIcon; } } public static Icon getDisabledIcon(final String imageName) { Icon disabledIcon = DISABLED_ICON_CACHE.get(imageName); if (disabledIcon == null) { final Image image = getDisabledImage(imageName); if (image == null) { return null; } else { disabledIcon = new ImageIcon(image, imageName); DISABLED_ICON_CACHE.put(imageName, disabledIcon); final Icon icon = getIcon(imageName); DISABLED_ICON_BY_ICON.put(icon, disabledIcon); } } return disabledIcon; } public static BufferedImage getDisabledImage(final Image image) { BufferedImage disabledImage = DISABLED_IMAGE_CACHE.get(image); if (disabledImage == null) { disabledImage = alpha(image, 0.30f); DISABLED_IMAGE_CACHE.put(image, disabledImage); } return disabledImage; } public static Image getDisabledImage(final String imageName) { BufferedImage image = null; final Reference<BufferedImage> imageReference = NAMED_DISABLED_IMAGE_CACHE.get(imageName); if (imageReference != null) { image = imageReference.get(); } if (image == null) { image = getImage(imageName); if (image != null) { image = getDisabledImage(image); NAMED_DISABLED_IMAGE_CACHE.put(imageName, new WeakReference<>(image)); } } return image; } public static Icon getIcon(final IconNameProxy iconNameProxy) { final String iconName = iconNameProxy.getIconName(); if (Property.hasValue(iconName)) { return getIcon(iconName); } else { return null; } } public static Icon getIcon(final String imageName) { if (Property.hasValue(imageName)) { Icon icon = ICON_CACHE.get(imageName); if (icon == null) { final String[] parts = imageName.split(":"); if (parts.length == 1) { if ("folder".equals(imageName)) { final UIDefaults uiDefaults = UIManager.getDefaults(); final Icon folderIcon = uiDefaults.getIcon("Tree.closedIcon"); setIcon(imageName, folderIcon); return folderIcon; } else { final Image image = getImage(imageName); if (image == null) { return null; } else { icon = new ImageIcon(image, imageName); setIcon(imageName, icon); } } } else { return getIconWithBadge(parts[0], parts[1]); } } return icon; } else { return null; } } public static Icon getIconWithBadge(final Icon baseIcon, final String badgeName) { final BufferedImage image = new BufferedImage(baseIcon.getIconWidth(), baseIcon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); final Graphics graphics = image.createGraphics(); baseIcon.paintIcon(null, graphics, 0, 0); final Image badgeImage = getBadgeImage(badgeName); graphics.drawImage(badgeImage, 0, 0, null); graphics.dispose(); return new ImageIcon(image); } public static Icon getIconWithBadge(final String iconName, final String badgeName) { final Icon icon = getIcon(iconName); return getIconWithBadge(icon, badgeName); } protected static BufferedImage getImage(final InputStream in) { if (in != null) { try { final BufferedImage image = ImageIO.read(in); final BufferedImage convertedImg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); final Graphics graphics = convertedImg.getGraphics(); graphics.drawImage(image, 0, 0, null); graphics.dispose(); return convertedImg; } catch (final IOException e) { } } return null; } public static BufferedImage getImage(final String imageName) { BufferedImage image = null; final Reference<BufferedImage> imageReference = NAMED_IMAGE_CACHE.get(imageName); if (imageReference != null) { image = imageReference.get(); } if (image == null) { image = getImage(imageName, "png"); if (image == null) { image = getImage(imageName, "gif"); } NAMED_IMAGE_CACHE.put(imageName, new WeakReference<>(image)); } return image; } public static BufferedImage getImage(final String imageName, final String fileExtension) { final Class<?> clazz = Icons.class; final String resourceName = RESOURCE_FOLDER + imageName + "." + fileExtension; InputStream in = clazz.getResourceAsStream(resourceName); if (in == null) { in = Thread.currentThread() .getContextClassLoader() .getResourceAsStream("images/" + imageName + "." + fileExtension); if (in == null) { in = Thread.currentThread() .getContextClassLoader() .getResourceAsStream("icons/" + imageName + "." + fileExtension); } } return getImage(in); } public static BufferedImage grayscale(final BufferedImage original) { final int width = original.getWidth(); final int height = original.getHeight(); final int type = original.getType(); final BufferedImage newImage = new BufferedImage(width, height, type); final int[] avgLUT = new int[766]; for (int i = 0; i < avgLUT.length; i++) { avgLUT[i] = i / 3; } for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { final int rgb = original.getRGB(i, j); final int alpha = rgb >> 24 & 0xff; final int red = rgb >> 16 & 0xff; final int green = rgb >> 8 & 0xff; final int blue = rgb & 0xff; int newRgb = red + green + blue; newRgb = avgLUT[newRgb]; newRgb = WebColors.colorToRGB(alpha, newRgb, newRgb, newRgb); newImage.setRGB(i, j, newRgb); } } return newImage; } public static Icon merge(final List<Icon> icons, final int space) { int maxWidth = 0; int maxHeight = 0; int i = 0; final StringBuilder descriptions = new StringBuilder(); for (final Icon icon : icons) { if (icon != null) { maxWidth += icon.getIconWidth(); maxHeight = Math.max(maxHeight, icon.getIconHeight()); final String iconDescription = icon.toString(); if (i > 0) { descriptions.append(':'); } descriptions.append(iconDescription); i++; } } maxWidth += (i - 1) * space; if (maxWidth == 0) { return null; } if (maxHeight == 0) { return null; } final BufferedImage newImage = new BufferedImage(maxWidth, maxHeight, BufferedImage.TYPE_INT_ARGB); final Graphics g = newImage.createGraphics(); int x = 0; for (final Icon icon : icons) { if (icon != null) { final Image image = ((ImageIcon)icon).getImage(); final int iconWidth = icon.getIconWidth(); final int iconHeight = icon.getIconHeight(); g.drawImage(image, x, 0, iconWidth, iconHeight, null); x += iconWidth; x += space; } } return new ImageIcon(newImage, descriptions.toString()); } public static void setIcon(final String iconName, final Icon icon) { ICON_CACHE.put(iconName, icon); } }