/* * 09/05/2004 * * IconGroup.java - Class encapsulating images used for RTextArea actions. * * This library is distributed under a modified BSD license. See the included * RSyntaxTextArea.License.txt file for details. */ package org.fife.ui.rtextarea; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.URL; import java.security.AccessControlException; import javax.imageio.ImageIO; import javax.swing.Icon; import javax.swing.ImageIcon; /** * This class encapsulates the location, properties, etc. of an icon set used * for an instance of <code>RTextArea</code>. If the location of the icon * group is invalid in any way, any attempt to retrieve icons from an icon * group will return <code>null</code>. * * @author Robert Futrell * @version 0.5 */ public class IconGroup { private String path; private boolean separateLargeIcons; private String largeIconSubDir; private String extension; private String name; private String jarFile; private static final String DEFAULT_EXTENSION = "gif"; /** * Creates an icon set without "large versions" of the icons. * * @param name The name of the icon group. * @param path The directory containing the icon group. */ public IconGroup(String name, String path) { this(name, path, null); } /** * Constructor. * * @param name The name of the icon group. * @param path The directory containing the icon group. * @param largeIconSubDir The subdirectory containing "large versions" of * the icons. If no subdirectory exists, pass in <code>null</code>. */ public IconGroup(String name, String path, String largeIconSubDir) { this(name, path, largeIconSubDir, DEFAULT_EXTENSION); } /** * Constructor. * * @param name The name of the icon group. * @param path The directory containing the icon group. * @param largeIconSubDir The subdirectory containing "large versions" of * the icons. If no subdirectory exists, pass in <code>null</code>. * @param extension The extension of the icons (one of <code>gif</code>, * <code>jpg</code>, or <code>png</code>). */ public IconGroup(String name, String path, String largeIconSubDir, String extension) { this(name, path, largeIconSubDir, extension, null); } /** * Constructor. * * @param name The name of the icon group. * @param path The directory containing the icon group. * @param largeIconSubDir The subdirectory containing "large versions" of * the icons. If no subdirectory exists, pass in <code>null</code>. * @param extension The extension of the icons (one of <code>gif</code>, * <code>jpg</code>, or <code>png</code>). * @param jar The Jar file containing the icons, or <code>null</code> if * the icons are on the local file system. If a Jar is specified, * the value of <code>path</code> must be a path in the Jar file. * If this is not a valid Jar file, then no Jar file will be used, * meaning all icons returned from this icon group will be * <code>null</code>. */ public IconGroup(String name, String path, String largeIconSubDir, String extension, String jar) { this.name = name; this.path = path; if (path!=null && path.length()>0 && !path.endsWith("/")) { this.path += "/"; } this.separateLargeIcons = (largeIconSubDir!=null); this.largeIconSubDir = largeIconSubDir; this.extension = extension!=null ? extension : DEFAULT_EXTENSION; this.jarFile = jar; } /** * Returns whether two icon groups are equal. * * @param o2 The object to check against. * @return Whether <code>o2</code> represents the same icons as this icon * group. */ @Override public boolean equals(Object o2) { if (o2!=null && o2 instanceof IconGroup) { IconGroup ig2 = (IconGroup)o2; if (ig2.getName().equals(getName()) && separateLargeIcons==ig2.hasSeparateLargeIcons()) { if (separateLargeIcons) { if (!largeIconSubDir.equals(ig2.largeIconSubDir)) return false; } return path.equals(ig2.path); } // If we got here, separateLargeIcons values weren't equal. } return false; } /** * Returns the icon from this icon group with the specified name. * * @param name The name of the icon. For example, if you want the icon * specified in <code>new.gif</code>, this value should be * <code>new</code>. * @return The icon, or <code>null</code> if it could not be found or * loaded. * @see #getLargeIcon */ public Icon getIcon(String name) { Icon icon = getIconImpl(path + name + "." + extension); // JDK 6.0 b74 returns icons with width/height==-1 in certain error // cases (new ImageIcon(url) where url is not resolved?). We'll // just return null in this case as Swing AbstractButtons throw // exceptions when expected to paint an icon with width or height // is less than 1. if (icon!=null && (icon.getIconWidth()<1 || icon.getIconHeight()<1)) { icon = null; } return icon; } /** * Does the dirty work of loading an image. * * @param iconFullPath The full path to the icon, either on the local * file system or in the Jar file, if this icon group represents * icons in a Jar file. * @return The icon. */ private Icon getIconImpl(String iconFullPath) { try { if (jarFile==null) { // First see if it's on our classpath (e.g. an icon in // RText.jar, so we'd need to use the class loader). URL url = getClass().getClassLoader(). getResource(iconFullPath); if (url!=null) return new ImageIcon(url); // If not, see if it's a plain file on disk. BufferedImage image = ImageIO.read(new File(iconFullPath)); return image!=null ? new ImageIcon(image) : null; } else { // If it's in a Jar, create a URL and grab it. URL url = new URL("jar:file:///" + jarFile + "!/" + iconFullPath); //System.err.println("***** " + url.toString()); return new ImageIcon(url); } } catch (AccessControlException ace) { return null; // Likely in an applet or WebStart } catch (IOException ioe) { return null; } } /** * Returns the large icon from this icon group with the specified name. * If this icon group does not have large icons, <code>null</code> is * returned. * * @param name The name of the icon. For example, if you want the icon * specified in <code>new.gif</code>, this value should be * <code>new</code>. * @return The icon, or <code>null</code> if it could not be found or * loaded. * @see #getLargeIcon */ public Icon getLargeIcon(String name) { return getIconImpl(path + largeIconSubDir + "/" + name + "." + extension); } /** * Returns the name of this icon group. * * @return This icon group's name. */ public String getName() { return name; } /** * Returns whether a separate directory for the large icons exists. * * @return Whether a directory containing "large versions" ov the icons * exists. * @see #getLargeIcon(String) */ public boolean hasSeparateLargeIcons() { return separateLargeIcons; } /** * Overridden since we also override {@link #equals(Object)}, to honor * the invariant that equal objects must have equal hashcodes. This also * keeps FindBugs happy. */ @Override public int hashCode() { return getName().hashCode(); } }