All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jidesoft.icons.IconsFactory Maven / Gradle / Ivy

There is a newer version: 3.6.18
Show newest version
/*
 * @(#)IconsFactory.java
 *
 * Copyright 2002 JIDE Software Inc. All rights reserved.
 */
package com.jidesoft.icons;

import com.jidesoft.swing.JideSwingUtilities;
import com.jidesoft.utils.SecurityUtils;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Logger;

/**
 * IconsFactory provides a consistent way to access icon resource in any application.
 * 

* Any application usually need to access image files. One way to do it is to put those image files in the installation * and access them use direct file access. However this is not a good way because you have to know the full path to the * image file. So a better way that most Java applications take is to bundle the image files with in the jar and use * class loader to load them. *

* For example, if a class Foo needs to access image files foo.gif and bar.png, we put the image files right below the * source code under icons subfolder. See an example directory structure below. *

 * /src/com/jidesoft/Foo.java
 *                  /icons/foo.gif
 *                  /icons/bar.png
 * 
* When you compile the java class, you copy those images to class output directory like this. *
 * /classes/com/jidesoft/Foo.class
 *                      /icons/foo.gif
 *                      /icons/bar.png
 * 
* Notes: In IntelliJ IDEA's "Compile" tab of "Project Property" dialog, there is a way to set "Resource Pattern". * Here is the setting on my computer - "?*.properties;?*.xml;?*.html;?*.tree;?*.gif;?*.png;?*.jpeg;?*.jpg;?*.vm;?*.xsd;?*.ilayout;?*.gz;?*.txt" * for your reference. If so, all your images will get copies automatically to class output folder. Although I haven't * tried, I believe most Java IDEs have the same or similar feature. This feature will make the usage of IconsFactory * much easier. *

* If you setup directory structure as above, you can now use IconsFactory to access the images like this. *


 * ImageIcon icon = IconsFactory.get(Foo.class, "icons/foo.gif");
 * 
* IconsFactory will cache the icon for you. So next time if you get the same icon, it will get from cache instead of * reading from disk again. *

* There are a few methods on IconsFactory to create difference variation from the original icon. For example, {@link * #getDisabledImageIcon(Class, String)} will get the image icon with disabled effect. *

* We also suggest you to use the template below to create a number of IconsFactory classes in your application. The * idea is that you should have one for each functional area so that all your image files can be grouped into each * functional area. All images used in that functional area should be put under the folder where this IconsFactory is. * Here is an template. *


 * class TemplateIconsFactory {
 *    public static class Group1 {
 *        public static final String IMAGE1 = "icons/image11.png";
 *        public static final String IMAGE2 = "icons/image12.png";
 *        public static final String IMAGE3 = "icons/image13.png";
 *    }
 * 

* public static class Group2 { * public static final String IMAGE1 = "icons/image21.png"; * public static final String IMAGE2 = "icons/image22.png"; * public static final String IMAGE3 = "icons/image23.png"; * } *

* public static ImageIcon getImageIcon(String name) { * if (name != null) * return IconsFactory.getImageIcon(TemplateIconsFactory.class, name); * else * return null; * } *

* public static void main(String[] argv) { * IconsFactory.generateHTML(TemplateIconsFactory.class); * } * } *

* In your own IconsFactory, you can further divide images into different groups. The example above has two groups. * There is also a convenient method getImageIcon() which takes just the icon name. *

* In the template, we defined the image names as constants. When you have a lot of images, it's hard to remember all of * them when writing code. If using the IconsFactory above, you can use *


 * ImageIcon icon = TemplateIconsFactory.getImageIcon(TemplateIconsFactory.Group1.IMAGE1);
 * 
* without saying the actual image file name. With the help of intelli-sense (or code completion) feature in most Java * IDE, you will find it is much easier to find the icons you want. You can refer to JIDE Components Developer Guide to * see a screenshot of what it looks like in IntelliJ IDEA. *

* You probably also notice this is a main() method in this template. You can run it. When you run, you will see a * message printed out like this. *


 * "File is generated at "... some directory ...\com.jidesoft.icons.TemplateIconsFactory.html".
 * Please copy it to the same directory as TemplateIconsFactory.java"
 * 
* if you follow the instruction and copy the html file to the same location as the source code and open the html, you * will see the all image files defined in this IconsFactory are listed nicely in the page. *

* By default, all image files are loaded using ImageIO. However if you set system property "jide.useImageIO" to * "false", we will disable the usage of ImageIO and use Toolkit.getDefaultToolkit().createImage method to create the * image file. */ public class IconsFactory { static Map _icons = new HashMap(); static Map _disableIcons = new HashMap(); static Map _brighterIcons = new HashMap(); static Map _tintedIcons = new HashMap(); public static ImageIcon EMPTY_ICON = new ImageIcon() { private static final long serialVersionUID = 5081581607741629368L; @Override public int getIconHeight() { return 16; } @Override public int getIconWidth() { return 16; } @Override public synchronized void paintIcon(Component c, Graphics g, int x, int y) { } }; /** * Gets ImageIcon by passing class and a relative image file path. *

* Please note, getImageIcon will print out error message to stderr if image is not found. The reason we did so is * because we want you to make sure all image files are there in your application. If you ever see the error * message, you should correct it before shipping the product. But if you just want to test if the image file is * there, you don't want any error message print out. If so, you can use {@link #findImageIcon(Class, String)} * method. It will throw IOException when image is not found. *

* We used this method to create all the icons we used in JIDE's code. If you ever want to use your own icon instead * of JIDE's default icon, you just need to put it onto UIManager. For example, AutoFilterTableHeader uses an icon * on the table header. This is how it was called.
IconsFactory.getImageIcon(AutoFilterTableHeader.class, * "icons/filterYes_over.png") *

* The key for this icon is "com.jidesoft.grid.AutoFilterTableHeader:icons/filterYes_over.png". So you can call the * code below to register your own icon.

UIManager.put("com.jidesoft.grid.AutoFilterTableHeader:icons/filterYes_over.png", * your_new_icon); *

* If you don't know what key to use, just put a breakpoint at this method, run it to inspect the id variable * below. * * @param clazz the Class * @param fileName relative file name * @return the ImageIcon */ public static ImageIcon getImageIcon(Class clazz, String fileName) { String id = clazz.getName() + ":" + fileName; Object iconInUIDefaults = UIManager.getDefaults().get(id); if (iconInUIDefaults instanceof ImageIcon) { return (ImageIcon) iconInUIDefaults; } Icon saved = _icons.get(id); if (saved != null) return (ImageIcon) saved; else { ImageIcon icon = createImageIcon(clazz, fileName); _icons.put(id, icon); return icon; } } /** * Gets ImageIcon by passing class and a relative image file path. * * @param clazz the Class * @param fileName relative file name * @return the ImageIcon * * @throws IOException when image file is not found. */ public static ImageIcon findImageIcon(Class clazz, String fileName) throws IOException { String id = clazz.getName() + ":" + fileName; Object iconInUIDefaults = UIManager.getDefaults().get(id); if (iconInUIDefaults instanceof ImageIcon) { return (ImageIcon) iconInUIDefaults; } ImageIcon saved = _icons.get(id); if (saved != null) return saved; else { ImageIcon icon = createImageIconWithException(clazz, fileName); _icons.put(id, icon); return icon; } } /** * Gets a disabled version of ImageIcon by passing class and a relative image file path. * * @param clazz the Class * @param fileName relative file name * @return the ImageIcon */ public static ImageIcon getDisabledImageIcon(Class clazz, String fileName) { String id = clazz.getName() + ":" + fileName; ImageIcon saved = _disableIcons.get(id); if (saved != null) return saved; else { ImageIcon icon = createGrayImage(getImageIcon(clazz, fileName)); _disableIcons.put(id, icon); return icon; } } /** * Gets a brighter ImageIcon by passing class and a relative image file path. * * @param clazz the Class * @param fileName relative file name * @return the ImageIcon */ public static ImageIcon getBrighterImageIcon(Class clazz, String fileName) { String id = clazz.getName() + ":" + fileName + ":" + ColorFilter.getPercent(); ImageIcon saved = _brighterIcons.get(id); if (saved != null) return saved; else { ImageIcon icon = createBrighterImage(getImageIcon(clazz, fileName)); _brighterIcons.put(id, icon); return icon; } } /** * Gets a brighter ImageIcon by passing class, a relative image file path and a percentage of brightness. * * @param clazz the Class * @param fileName relative file name * @param percent percentage of brightness * @return the ImageIcon */ public static ImageIcon getBrighterImageIcon(Class clazz, String fileName, int percent) { String id = clazz.getName() + ":" + fileName + ":" + percent; ImageIcon saved = _brighterIcons.get(id); if (saved != null) return saved; else { ImageIcon icon = createBrighterImage(getImageIcon(clazz, fileName), percent); _brighterIcons.put(id, icon); return icon; } } /** * Gets a tinted ImageIcon by passing class, a relative image file path and a color. * * @param clazz the Class * @param fileName relative file name * @param color the color * @return the ImageIcon */ public static ImageIcon getTintedImageIcon(Class clazz, String fileName, Color color) { String id = clazz.getName() + ":" + fileName + ":" + color.toString(); ImageIcon saved = _tintedIcons.get(id); if (saved != null) return saved; else { ImageIcon icon = createTintedImage(getImageIcon(clazz, fileName), color); _tintedIcons.put(id, icon); return icon; } } /** * Creates a gray version from an input image. Usually gray icon indicates disabled. If input image is null, a blank * ImageIcon will be returned. * * @param image image * @return gray version of the image */ public static ImageIcon createGrayImage(Image image) { if (image == null) return EMPTY_ICON; return new ImageIcon(GrayFilter.createDisabledImage(image)); } /** * Creates a gray version from an input ImageIcon. Usually gray icon indicates disabled. If input icon is null, a * blank ImageIcon will be returned. * * @param icon image * @return gray version of the image */ private static ImageIcon createGrayImage(ImageIcon icon) { if (icon == null) return EMPTY_ICON; return new ImageIcon(GrayFilter.createDisabledImage(icon.getImage())); } /** * Creates a gray version from an input image. Usually gray icon indicates disabled. If input icon is null, a blank * ImageIcon will be returned. * * @param c The component to get properties useful for painting, e.g. the foreground or background color. * @param icon icon * @return gray version of the image */ public static ImageIcon createGrayImage(Component c, Icon icon) { if (icon == null) return EMPTY_ICON; int w = icon.getIconWidth(), h = icon.getIconHeight(); if ((w == 0) || (h == 0)) return EMPTY_ICON; BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); icon.paintIcon(c, image.getGraphics(), 0, 0); return new ImageIcon(GrayFilter.createDisabledImage(image)); } /** * Creates a brighter image from an input image. If input image is null, a blank ImageIcon will be returned. * * @param image image * @return dimmed version of the image */ public static ImageIcon createBrighterImage(Image image) { if (image == null) return EMPTY_ICON; return new ImageIcon(ColorFilter.createBrighterImage(image)); } /** * Creates a brighter image from an input image with a given percentage of brightness. If input image is null, a * blank ImageIcon will be returned. * * @param image image * @param percent percentage of brightness * @return dimmed version of the image */ public static ImageIcon createBrighterImage(Image image, int percent) { if (image == null) return EMPTY_ICON; return new ImageIcon(ColorFilter.createBrighterImage(image, percent)); } /** * Creates a gray version from an input image. Usually gray icon indicates disabled. If input icon is null, a blank * ImageIcon will be returned. * * @param c The component to get properties useful for painting, e.g. the foreground or background color. * @param icon icon * @return gray version of the image */ public static ImageIcon createBrighterImage(Component c, Icon icon) { if (icon == null) return EMPTY_ICON; BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); icon.paintIcon(c, image.getGraphics(), 0, 0); return new ImageIcon(ColorFilter.createBrighterImage(image)); } /** * Creates a gray version from an input image with a given percentage of brightness. Usually gray icon indicates * disabled. If input icon is null, a blank ImageIcon will be returned. * * @param c The component to get properties useful for painting, e.g. the foreground or background color. * @param icon icon * @param percent percentage of brightness * @return gray version of the image */ public static ImageIcon createBrighterImage(Component c, Icon icon, int percent) { if (icon == null) return EMPTY_ICON; BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); icon.paintIcon(c, image.getGraphics(), 0, 0); return new ImageIcon(ColorFilter.createBrighterImage(image, percent)); } /** * Creates a brighten version from an input ImageIcon. If input icon is null, a blank ImageIcon will be returned. * * @param icon image * @return dimmed version of the image */ public static ImageIcon createBrighterImage(ImageIcon icon) { if (icon == null) return EMPTY_ICON; return new ImageIcon(ColorFilter.createBrighterImage(icon.getImage())); } /** * Creates a brighter image from an input image with a given percentage of brightness. If input image is null, a * blank ImageIcon will be returned. * * @param icon image * @param percent percentage of brightness * @return dimmed version of the image */ public static ImageIcon createBrighterImage(ImageIcon icon, int percent) { if (icon == null) return EMPTY_ICON; return new ImageIcon(ColorFilter.createBrighterImage(icon.getImage(), percent)); } /** * Creates a tinted image from an input image with a given color. If input image is null, a blank ImageIcon will be * returned. * * @param icon image * @param color the color * @return a tinted version of the image */ public static ImageIcon createTintedImage(ImageIcon icon, Color color) { if (icon == null) return EMPTY_ICON; return new ImageIcon(TintFilter.createTintedImage(icon.getImage(), color, null)); } /** * Creates a gray version from an input image. Usually gray icon indicates disabled. If input image is null, a blank * ImageIcon will be returned. * * @param image image * @return gray version of the image */ public static ImageIcon createNegativeImage(Image image) { if (image == null) return EMPTY_ICON; return new ImageIcon(MaskFilter.createNegativeImage(image)); } /** * Creates a version from an input image which replaces one color with another color. * * @param c The component to get properties useful for painting, e.g. the foreground or background color. * @param icon icon * @param oldColor the old color to be replaced. * @param newColor the new color that will replace the old color. * @return the image after replacing the color. */ public static ImageIcon createMaskImage(Component c, Icon icon, Color oldColor, Color newColor) { BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); icon.paintIcon(c, image.getGraphics(), 0, 0); return new ImageIcon(MaskFilter.createImage(image, oldColor, newColor)); } static final double DEGREE_90 = 90.0 * Math.PI / 180.0; /** * Creates a rotated version of the input image. * * @param c The component to get properties useful for painting, e.g. the foreground or background * color. * @param icon the image to be rotated. * @param rotatedAngle the rotated angle, in degree, clockwise. It could be any double but we will mod it with 360 * before using it. * @return the image after rotating. */ public static ImageIcon createRotatedImage(Component c, Icon icon, double rotatedAngle) { // convert rotatedAngle to a value from 0 to 360 double originalAngle = rotatedAngle % 360; if (rotatedAngle != 0 && originalAngle == 0) { originalAngle = 360.0; } // convert originalAngle to a value from 0 to 90 double angle = originalAngle % 90; if (originalAngle != 0.0 && angle == 0.0) { angle = 90.0; } double radian = Math.toRadians(angle); int iw = icon.getIconWidth(); int ih = icon.getIconHeight(); int w; int h; if ((originalAngle >= 0 && originalAngle <= 90) || (originalAngle > 180 && originalAngle <= 270)) { w = (int) Math.round((iw * Math.sin(DEGREE_90 - radian) + ih * Math.sin(radian))); h = (int) Math.round((iw * Math.sin(radian) + ih * Math.sin(DEGREE_90 - radian))); } else { w = (int) (ih * Math.sin(DEGREE_90 - radian) + iw * Math.sin(radian)); h = (int) (ih * Math.sin(radian) + iw * Math.sin(DEGREE_90 - radian)); } BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics g = image.getGraphics(); Graphics2D g2d = (Graphics2D) g.create(); // calculate the center of the icon. int cx = iw / 2; int cy = ih / 2; // account for images that have a center point in the middle of a pixel. // for these images (not divisible by two) we need to account for the // "down and to the right" bias of the graphics context. int xOffset = iw % 2 != 0 && originalAngle >= 90 && originalAngle <= 180 ? 1 : 0; int yOffset = iw % 2 != 0 && originalAngle >= 180 && originalAngle < 360 ? 1 : 0; // move the graphics center point to the center of the icon. g2d.translate(w / 2 + xOffset, h / 2 + yOffset); // rotate the graphics about the center point of the icon g2d.rotate(Math.toRadians(originalAngle)); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); icon.paintIcon(c, g2d, -cx, -cy); g2d.dispose(); return new ImageIcon(image); } /** * Creates a negative version from an input black image which basically replaces black pixel with white pixel. * * @param c The component to get properties useful for painting, e.g. the foreground or background color. * @param icon icon * @return the negative version of the image */ public static ImageIcon createNegativeImage(Component c, Icon icon) { BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); icon.paintIcon(c, image.getGraphics(), 0, 0); return new ImageIcon(MaskFilter.createNegativeImage(image)); } private static ImageIcon createImageIcon(final Class baseClass, final String file) { try { return createImageIconWithException(baseClass, file); } catch (IOException e) { System.err.println(e.getLocalizedMessage()); return null; } } private static ImageIcon createImageIconWithException(final Class baseClass, final String file) throws IOException { InputStream resource = baseClass.getResourceAsStream(file); if (resource == null) { throw new FileNotFoundException(file); } else { Image image; if ("true".equals(SecurityUtils.getProperty("jide.useImageIO", "true"))) { image = ImageIO.read(resource); } else { image = readImageIcon(baseClass, file, resource); } resource.close(); return new ImageIcon(image); } } private static Image readImageIcon(Class clazz, String file, InputStream resource) throws IOException { final byte[][] buffer = new byte[1][]; try { BufferedInputStream in = new BufferedInputStream(resource); ByteArrayOutputStream out = new ByteArrayOutputStream(1024); buffer[0] = new byte[1024]; int n; while ((n = in.read(buffer[0])) > 0) { out.write(buffer[0], 0, n); } in.close(); out.flush(); buffer[0] = out.toByteArray(); } catch (IOException ioe) { throw ioe; } if (buffer[0] == null || buffer[0].length == 0) { Package pkg = clazz.getPackage(); String pkgName = ""; if (pkg != null) { pkgName = pkg.getName().replace('.', '/'); } if (buffer[0] == null) { throw new IOException("Warning: Resource " + pkgName + "/" + file + " not found."); } if (buffer[0].length == 0) { throw new IOException("Warning: Resource " + pkgName + "/" + file + " is zero-length"); } } return Toolkit.getDefaultToolkit().createImage(buffer[0]); } /** * Generates HTML that lists all icons in IconsFactory. * * @param clazz the IconsFactory class */ public static void generateHTML(Class clazz) { String fullClassName = clazz.getName(); String className = getClassName(fullClassName); File file = new File(fullClassName + ".html"); try { FileWriter writer = new FileWriter(file); try { writer.write("\n\n

Icons in " + fullClassName + "

"); writer.write("

Generated by JIDE Icons

"); writer.write("

1. If you cannot view the images in this page, " + "make sure the file is at the same directory as " + className + ".java

"); writer.write("

2. To get a particular icon in your code, call " + className + ".getImageIcon(FULL_CONSTANT_NAME). Replace FULL_CONSTANT_NAME with the actual " + "full constant name as in the table below" + "

"); generate(clazz, writer, className); writer.write("\n\n"); } catch (IOException e) { System.err.println(e); } finally { writer.close(); } System.out.println("File is generated at \"" + file.getAbsolutePath() + "\". Please copy it to the same directory as " + className + ".java"); } catch (IOException e) { System.err.println(e); } } private static String getClassName(String fullName) { int last = fullName.lastIndexOf("."); if (last != -1) { fullName = fullName.substring(last + 1); } StringTokenizer tokenizer = new StringTokenizer(fullName, "$"); StringBuffer buffer = new StringBuffer(); while (tokenizer.hasMoreTokens()) { buffer.append(tokenizer.nextToken()); buffer.append("."); } return buffer.substring(0, buffer.length() - 1); } private static void generate(Class aClass, FileWriter writer, String prefix) throws IOException { Class[] classes = aClass.getDeclaredClasses(); // don't know why but the order is exactly the reverse of the order of definitions. for (int i = classes.length - 1; i >= 0; i--) { Class clazz = classes[i]; generate(clazz, writer, getClassName(clazz.getName())); } Field[] fields = aClass.getFields(); writer.write("

" + prefix + "

"); writer.write(""); writer.write("\n"); writer.write("\n"); writer.write("\n"); writer.write("\n"); writer.write("\n"); writer.write("\n"); for (Field field : fields) { try { Object name = field.getName(); Object value = field.get(aClass); writer.write("\n"); writer.write("\n"); writer.write("\n"); writer.write("\n"); writer.write("\n"); writer.write("\n"); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } writer.write("
NameImageFile NameFull Constant Name
" + name + "" + value + "" + prefix + "." + name + "

\n"); } /** * Gets part of the image from input image icon. It basically takes a snapshot of the input image at {x, y} location * and the size is width x height. * * @param c the component where the returned icon will be used. The component is used as the ImageObserver. It * could be null. * @param icon the original icon. This is the larger icon where a sub-image will be created using this method. * @param x the x location of the sub-image, relative to the original icon. * @param y the y location of the sub-image, relative to the original icon. * @param width the width of the sub-image. It should be less than the width of the original icon. * @param height the height of the sub-image. It should be less than the height of the original icon. * @return an new image icon that was part of the input image icon. */ public static ImageIcon getIcon(Component c, ImageIcon icon, int x, int y, int width, int height) { return getIcon(c, icon, x, y, width, height, width, height); } /** * Gets part of the image from input image icon. It basically takes a snapshot of the input image at {x, y} location * and the size is width x height, then resize it to a size of destWidth x destHeight. * * @param c the component where the returned icon will be used. The component is used as the ImageObserver. * It could be null. * @param icon the original icon. This is the larger icon where a sub-image will be created using this * method. * @param x the x location of the sub-image, relative to the original icon. * @param y the y location of the sub-image, relative to the original icon. * @param width the width of the sub-image. It should be less than the width of the original icon. * @param height the height of the sub-image. It should be less than the height of the original icon. * @param destWidth the width of the returned icon. The sub-image will be resize if the destWidth is not the same * as the width. * @param destHeight the height of the returned icon. The sub-image will be resize if the destHeight is not the same * as the height. * @return an new image icon that was part of the input image icon. */ public static ImageIcon getIcon(Component c, ImageIcon icon, int x, int y, int width, int height, int destWidth, int destHeight) { return getIcon(c, icon, x, y, width, height, BufferedImage.TYPE_INT_ARGB, destWidth, destHeight); } /** * Gets part of the image from input image icon. It basically takes a snapshot of the input image at {x, y} location * and the size is width x height. * * @param c the component where the returned icon will be used. The component is used as the ImageObserver. * It could be null. * @param icon the original icon. This is the larger icon where a small icon will be created using this * method. * @param x the x location of the smaller icon, relative to the original icon. * @param y the y location of the smaller icon, relative to the original icon. * @param width the width of the smaller icon. It should be less than the width of the original icon. * @param height the height of the smaller icon. It should be less than the height of the original icon. * @param imageType image type is defined in {@link BufferedImage}, such as {@link BufferedImage#TYPE_INT_ARGB}, * {@link BufferedImage#TYPE_INT_RGB} etc. * @return an new image icon that was part of the input image icon. */ public static ImageIcon getIcon(Component c, ImageIcon icon, int x, int y, int width, int height, int imageType) { return getIcon(c, icon, x, y, width, height, imageType, width, height); } /** * Gets part of the image from input image icon. It basically takes a snapshot of the input image at {x, y} location * and the size is width x height, then resize it to a size of destWidth x destHeight. if the original icon is null * or the specified location is outside the original icon, EMPTY_ICON will be returned. * * @param c the component where the returned icon will be used. The component is used as the ImageObserver. * It could be null. * @param icon the original icon. This is the larger icon where a sub-image will be created using this * method. * @param x the x location of the sub-image, relative to the original icon. * @param y the y location of the sub-image, relative to the original icon. * @param width the width of the sub-image. It should be less than the width of the original icon. * @param height the height of the sub-image. It should be less than the height of the original icon. * @param imageType image type is defined in {@link BufferedImage}, such as {@link BufferedImage#TYPE_INT_ARGB}, * {@link BufferedImage#TYPE_INT_RGB} etc. * @param destWidth the width of the returned icon. The sub-image will be resize if the destWidth is not the same * as the width. * @param destHeight the height of the returned icon. The sub-image will be resize if the destHeight is not the same * as the height. * @return an new image icon that was part of the input image icon. */ public static ImageIcon getIcon(Component c, ImageIcon icon, int x, int y, int width, int height, int imageType, int destWidth, int destHeight) { if (icon == null || x < 0 || x + width > icon.getIconWidth() || y < 0 || y + height > icon.getIconHeight()) { // outside the original icon. return EMPTY_ICON; } BufferedImage image = new BufferedImage(destWidth, destHeight, imageType); image.getGraphics().drawImage(icon.getImage(), 0, 0, destWidth, destHeight, x, y, x + width, y + height, c); return new ImageIcon(image); } /** * Gets a new icon with the overlayIcon paints over the original icon. * * @param c the component where the returned icon will be used. The component is used as the * ImageObserver. It could be null. * @param icon the original icon * @param overlayIcon the overlay icon. * @param location the location as defined in SwingConstants - CENTER, NORTH, SOUTH, WEST, EAST, NORTH_EAST, * NORTH_WEST, SOUTH_WEST and SOUTH_EAST. * @return the new icon. */ public static ImageIcon getOverlayIcon(Component c, ImageIcon icon, ImageIcon overlayIcon, int location) { return getOverlayIcon(c, icon, overlayIcon, location, new Insets(0, 0, 0, 0)); } /** * Gets a new icon with the overlayIcon paints over the original icon. * * @param c the component where the returned icon will be used. The component is used as the * ImageObserver. It could be null. * @param icon the original icon * @param overlayIcon the overlay icon. * @param location the location as defined in SwingConstants - CENTER, NORTH, SOUTH, WEST, EAST, NORTH_EAST, * NORTH_WEST, SOUTH_WEST and SOUTH_EAST. * @param insets the insets to the border. This parameter has no effect if the location is CENTER. For example, * if the location is WEST, insets.left will be the gap of the left side of the original icon and * the left side of the overlay icon. * @return the new icon. */ public static ImageIcon getOverlayIcon(Component c, ImageIcon icon, ImageIcon overlayIcon, int location, Insets insets) { int x = -1, y = -1; int w = icon.getIconWidth(); int h = icon.getIconHeight(); int sw = overlayIcon.getIconWidth(); int sh = overlayIcon.getIconHeight(); switch (location) { case SwingConstants.CENTER: x = (w - sw) / 2; y = (h - sh) / 2; break; case SwingConstants.NORTH: x = (w - sw) / 2; y = insets.top; break; case SwingConstants.SOUTH: x = (w - sw) / 2; y = h - insets.bottom - sh; break; case SwingConstants.WEST: x = insets.left; y = (h - sh) / 2; break; case SwingConstants.EAST: x = w - insets.right - sw; y = (h - sh) / 2; break; case SwingConstants.NORTH_EAST: x = w - insets.right - sw; y = insets.top; break; case SwingConstants.NORTH_WEST: x = insets.left; y = insets.top; break; case SwingConstants.SOUTH_WEST: x = insets.left; y = h - insets.bottom - sh; break; case SwingConstants.SOUTH_EAST: x = w - insets.right - sw; y = h - insets.bottom - sh; break; } return getOverlayIcon(c, icon, overlayIcon, x, y); } /** * Gets a new icon with the overlayIcon paints over the original icon. * * @param c the component where the returned icon will be used. The component is used as the * ImageObserver. It could be null. * @param icon the original icon * @param overlayIcon the overlay icon. * @param x the x location relative to the original icon where the overlayIcon will be pained. * @param y the y location relative to the original icon where the overlayIcon will be pained. * @return the overlay icon */ public static ImageIcon getOverlayIcon(Component c, ImageIcon icon, ImageIcon overlayIcon, int x, int y) { int w = icon == null ? overlayIcon.getIconWidth() : icon.getIconWidth(); int h = icon == null ? overlayIcon.getIconHeight() : icon.getIconHeight(); int sw = overlayIcon.getIconWidth(); int sh = overlayIcon.getIconHeight(); if (x != -1 && y != -1) { BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); if (icon != null) { image.getGraphics().drawImage(icon.getImage(), 0, 0, w, h, c); } image.getGraphics().drawImage(overlayIcon.getImage(), x, y, sw, sh, c); return new ImageIcon(image); } else { return icon; } } /** * Gets a new icon with the icon2 painting right or down to the icon1. * * @param c the component where the returned icon will be used. The component is used as the * ImageObserver. It could be null * @param icon1 the left side or up side icon * @param icon2 the right side or down side icon * @param orientation the orientation as defined in SwingConstants - HORIZONTAL, VERTICAL * @param gap the gap between the two icons * @return the new icon. */ public static ImageIcon getCombinedIcon(Component c, ImageIcon icon1, ImageIcon icon2, int orientation, int gap) { if (icon1 == null) { return icon2; } if (icon2 == null) { return icon1; } int x1, y1, x2, y2, width, height; int w1 = icon1.getIconWidth(); int h1 = icon1.getIconHeight(); int w2 = icon2.getIconWidth(); int h2 = icon2.getIconHeight(); if (orientation == SwingConstants.HORIZONTAL) { width = w1 + w2 + gap; height = Math.max(h1, h2); x1 = 0; x2 = w1 + gap; y1 = h1 > h2 ? 0 : (h2 - h1) / 2; y2 = h1 < h2 ? 0 : (h1 - h2) / 2; } else { width = Math.max(w1, w2); height = h1 + h2 + gap; x1 = w1 > w2 ? 0 : (w2 - w1) / 2; x2 = w1 < w2 ? 0 : (w1 - w2) / 2; y1 = 0; y2 = h1 + gap; } BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); image.getGraphics().drawImage(icon1.getImage(), x1, y1, w1, h1, c); image.getGraphics().drawImage(icon2.getImage(), x2, y2, w2, h2, c); return new ImageIcon(image); } /** * Gets a scaled version of the existing icon. * * @param c the component where the returned icon will be used. The component is used as the ImageObserver. It * could be null. * @param icon the original icon * @param w the new width * @param h the new height * @return the scaled icon */ public static ImageIcon getScaledImage(Component c, ImageIcon icon, int w, int h) { if (w >= icon.getIconWidth() / 2) { BufferedImage temp = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = temp.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g2.drawImage(icon.getImage(), 0, 0, temp.getWidth(), temp.getHeight(), c); g2.dispose(); return new ImageIcon(temp); } else { BufferedImage temp = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = temp.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2.drawImage(icon.getImage(), 0, 0, temp.getWidth(), temp.getHeight(), c); g2.dispose(); return new ImageIcon(JideSwingUtilities.getFasterScaledInstance(temp, w, h, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true)); } } /** * Writes a GIF image of the supplied component to the given file. In particular, you can use this method to take a * 'screen shot' of a Chart component as a GIF Image. * * @param c the component to save as an image * @param file the file to save it to * @throws FileNotFoundException if the file exists but is a directory rather than a regular file, does not exist * but cannot be created, or cannot be opened for any other reason */ public static void writeGifToFile(Component c, File file) throws FileNotFoundException { FileOutputStream fos = new FileOutputStream(file); writeToStream(c, "gif", fos); try { fos.close(); } catch (IOException e) { Logger.getAnonymousLogger().severe(e.getMessage()); } } /** * Writes a JPEG image of the supplied component to the given file. In particular, you can use this method to take a * 'screen shot' of a Chart component as a JPEG Image. * * @param c the component to save as an image * @param file the file to save it to * @throws FileNotFoundException if the file exists but is a directory rather than a regular file, does not exist * but cannot be created, or cannot be opened for any other reason */ public static void writeJpegToFile(Component c, File file) throws FileNotFoundException { FileOutputStream fos = new FileOutputStream(file); writeToStream(c, "jpg", fos); try { fos.close(); } catch (IOException e) { Logger.getAnonymousLogger().severe(e.getMessage()); } } /** * Writes a PNG image of the supplied component to the given file. In particular, you can use this method to take a * 'screen shot' of a Chart component as a PNG Image. * * @param c the component to save as an image * @param file the file to save it to * @throws FileNotFoundException if the file exists but is a directory rather than a regular file, does not exist * but cannot be created, or cannot be opened for any other reason */ public static void writePngToFile(Component c, File file) throws FileNotFoundException { FileOutputStream fos = new FileOutputStream(file); writeToStream(c, "png", fos); try { fos.close(); } catch (IOException e) { Logger.getAnonymousLogger().severe(e.getMessage()); } } /** * Paints the component as a PNG image to the supplied output stream * * @param c the component to capture as a PNG image * @param stream the stream to write the PNG data to */ public static void writeToStream(Component c, OutputStream stream) { writeToStream(c, "png", stream); } /** * Paints the component to the supplied output stream * * @param c the component to capture as an image * @param format the format of the image output data, currently "png", "jpg" or "gif" * @param stream the stream to write the image data to */ private static void writeToStream(Component c, String format, OutputStream stream) { BufferedImage img = createImage(c); try { ImageIO.write(img, format, stream); } catch (IOException e) { // could happen if the output format is not supported Logger.getAnonymousLogger().severe(e.getMessage()); } } /** * Creates a buffered image of type TYPE_INT_RGB from the supplied component. * * @param component the component to draw * @return an image of the component */ public static BufferedImage createImage(Component component) { return createImage(component, BufferedImage.TYPE_INT_RGB); } /** * Creates a buffered image (of the specified type) from the supplied component. * * @param component the component to draw * @param bounds the area relative to the component where the image will be created. * @param imageType the type of buffered image to draw * @return an image of the component */ public static BufferedImage createImage(final Component component, Rectangle bounds, int imageType) { BufferedImage img = new BufferedImage(bounds.width, bounds.height, imageType); final Graphics2D graphics = img.createGraphics(); graphics.fillRect(0, 0, img.getWidth(), img.getHeight()); // If we are painting a JComponent then switch off double buffering because it // causes a failure when running headlessly on Linux if (component instanceof JComponent) { JComponent c = (JComponent) component; boolean isDoubleBuffered = c.isDoubleBuffered(); c.setDoubleBuffered(false); graphics.translate(-bounds.x, -bounds.y); graphics.setClip(bounds.x, bounds.y, bounds.width, bounds.height); c.paint(graphics); c.setDoubleBuffered(isDoubleBuffered); } else { component.paint(graphics); } graphics.dispose(); return img; } /** * Creates a buffered image (of the specified type) from the supplied component. * * @param component the component to draw * @param imageType the type of buffered image to draw * @return an image of the component */ public static BufferedImage createImage(final Component component, int imageType) { Dimension componentSize = component.getSize(); BufferedImage img = new BufferedImage(componentSize.width, componentSize.height, imageType); final Graphics2D graphics = img.createGraphics(); graphics.fillRect(0, 0, img.getWidth(), img.getHeight()); // If we are painting a JComponent then switch off double buffering because it // causes a failure when running headlessly on Linux if (component instanceof JComponent) { JComponent c = (JComponent) component; boolean isDoubleBuffered = c.isDoubleBuffered(); c.setDoubleBuffered(false); c.paint(graphics); c.setDoubleBuffered(isDoubleBuffered); } else { component.paint(graphics); } graphics.dispose(); return img; } /** * Creates a thumbnail from the supplied component (such as a chart). If you want to display the thumbnail as a * component you can pass the created ImageIcon as a parameter to the constructor of a JLabel. * * @param component the component from which we would like to generate a thumbnail * @param width the width of the thumbnail * @param height the height of the thumbnail * @return a thumbnail Image of the supplied component */ public static Image createThumbnailImage(Component component, int width, int height) { BufferedImage image = createImage(component); BufferedImage thumbnailImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = thumbnailImage.createGraphics(); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); double w = (double) width / image.getWidth(); double h = (double) height / image.getHeight(); assert w <= 1.0 : "The thumbnail should be smaller than the original"; assert h <= 1.0 : "The thumbnail should be smaller than the original"; AffineTransform transform = AffineTransform.getScaleInstance(w, h); g.drawRenderedImage(image, transform); return thumbnailImage; } /** * Creates a thumbnail from the supplied component (such as a chart). If you want to display the thumbnail as a * component you can pass the created ImageIcon as a parameter to the constructor of a JLabel. * * @param component the component from which we would like to generate a thumbnail * @param width the width of the thumbnail * @param height the height of the thumbnail * @return an ImageIcon of the supplied component */ public static ImageIcon createThumbnail(Component component, int width, int height) { return new ImageIcon(createThumbnailImage(component, width, height)); } /** * Utility method to create a texture paint from a graphics file * * @param observer the observer to be informed when the texture image has been drawn * @param fileName the name of a file on the classpath, e.g., com/mycompany/project/images/widget.gif * @return a TexturePaint instance */ public static TexturePaint createTexture(JComponent observer, String fileName) { Image image = createImage(fileName); MediaTracker tracker = new MediaTracker(observer); tracker.addImage(image, 1); try { tracker.waitForAll(); } catch (Exception e) { } int w = image.getWidth(observer); int h = image.getHeight(observer); BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D big = bi.createGraphics(); big.drawImage(image, 0, 0, observer); return new TexturePaint(bi, new Rectangle(0, 0, bi.getWidth(), bi.getHeight())); } /** * Creates an image from a file on the classpath * * @param path the path to the file * @return an Image object */ public static Image createImage(String path) { ClassLoader loader = IconsFactory.class.getClassLoader(); if (loader != null) { URL url = loader.getResource(path); if (url == null) { url = loader.getResource("/" + path); } return Toolkit.getDefaultToolkit().createImage(url); } return null; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy