001/* 002 * Copyright 2006 - 2013 003 * Stefan Balev <stefan.balev@graphstream-project.org> 004 * Julien Baudry <julien.baudry@graphstream-project.org> 005 * Antoine Dutot <antoine.dutot@graphstream-project.org> 006 * Yoann Pigné <yoann.pigne@graphstream-project.org> 007 * Guilhelm Savin <guilhelm.savin@graphstream-project.org> 008 * 009 * This file is part of GraphStream <http://graphstream-project.org>. 010 * 011 * GraphStream is a library whose purpose is to handle static or dynamic 012 * graph, create them from scratch, file or any source and display them. 013 * 014 * This program is free software distributed under the terms of two licenses, the 015 * CeCILL-C license that fits European law, and the GNU Lesser General Public 016 * License. You can use, modify and/ or redistribute the software under the terms 017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following 018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by 019 * the Free Software Foundation, either version 3 of the License, or (at your 020 * option) any later version. 021 * 022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 024 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 025 * 026 * You should have received a copy of the GNU Lesser General Public License 027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 028 * 029 * The fact that you are presently reading this means that you have had 030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms. 031 */ 032package org.graphstream.ui.swingViewer.util; 033 034import java.awt.Color; 035import java.awt.Graphics2D; 036import java.awt.Image; 037import java.awt.image.BufferedImage; 038import java.io.File; 039import java.io.IOException; 040import java.net.URL; 041import java.util.HashMap; 042 043import javax.imageio.ImageIO; 044 045/** 046 * A simple cache for images to avoid reloading them constantly and to allow 047 * sharing. 048 * 049 * TODO have a policy to release images if they have not been used for a given 050 * time. 051 */ 052public class ImageCache { 053 /** 054 * The image cache. 055 */ 056 protected HashMap<String, Image> imageCache = new HashMap<String, Image>(); 057 058 /** 059 * The dummy image used to mark a not found image (and avoid trying to 060 * reload it again and again). 061 */ 062 protected Image dummy; 063 064 /** 065 * The default singleton image cache instance. 066 */ 067 protected static ImageCache defaultImageCache; 068 069 /** 070 * New empty image cache. 071 */ 072 public ImageCache() { 073 BufferedImage img = new BufferedImage(16, 16, 074 BufferedImage.TYPE_INT_RGB); 075 Graphics2D g2 = img.createGraphics(); 076 077 g2.setColor(Color.RED); 078 g2.drawRect(0, 0, img.getWidth() - 1, img.getHeight() - 1); 079 g2.drawLine(0, 0, img.getWidth() - 1, img.getHeight() - 1); 080 g2.drawLine(0, img.getHeight() - 1, img.getWidth() - 1, 0); 081 082 dummy = img; 083 } 084 085 /** 086 * Default singleton image cache instance that can be shared. This method 087 * and singleton must be used only in the Swing thread. 088 * 089 * @return The default singleton image cache instance. 090 */ 091 public static ImageCache defaultImageCache() { 092 if (defaultImageCache == null) 093 defaultImageCache = new ImageCache(); 094 095 return defaultImageCache; 096 } 097 098 /** 099 * Lookup an image based on its name, if found return it, else try to load 100 * it. If an image is not found once, the cache remembers it and will not 101 * try to reload it again if the same image is requested anew. Therefore 102 * using getImage() is fast and smooth. 103 * 104 * @param fileNameOrUrl 105 * A file name or an URL pointing at the image. 106 * @return An image or null if the image cannot be found. 107 */ 108 public Image getImage(String fileNameOrUrl) { 109 return getImage(fileNameOrUrl, false); 110 } 111 112 /** 113 * The same as {@link #getImage(String)} but you can force the cache to try 114 * to reload an image that where not found before. 115 * 116 * @param fileNameOrUrl 117 * A file name or an URL pointing at the image. 118 * @param forceTryReload 119 * If true, try to reload an image that where not found before. 120 * @return An image or null if the image cannot be found. 121 */ 122 public Image getImage(String fileNameOrUrl, boolean forceTryReload) { 123 Image ii = imageCache.get(fileNameOrUrl); 124 125 if (ii == dummy && !forceTryReload) 126 return null; 127 128 if (ii == null) { 129 URL url = ImageCache.class.getClassLoader().getResource( 130 fileNameOrUrl); 131 132 if (url != null) { 133 try { 134 ii = ImageIO.read(url); 135 imageCache.put(fileNameOrUrl, ii); 136 } catch (IOException e) { 137 e.printStackTrace(); 138 } 139 } else { 140 try { 141 url = new URL(fileNameOrUrl); 142 143 ii = ImageIO.read(url); 144 imageCache.put(fileNameOrUrl, ii); 145 } catch (Exception e) { 146 try { 147 ii = ImageIO.read(new File(fileNameOrUrl)); 148 imageCache.put(fileNameOrUrl, ii); 149 } catch (IOException ee) { 150 imageCache.put(fileNameOrUrl, dummy); 151 // ee.printStackTrace(); 152 System.err.printf("Cannot read image '%s'%n", 153 fileNameOrUrl); 154 } 155 } 156 } 157 } 158 159 return ii; 160 } 161 162 /** 163 * A dummy 16x16 image. 164 * 165 * @return An image. 166 */ 167 public Image getDummyImage() { 168 return dummy; 169 } 170}