001 /*
002 * This file is part of muCommander, http://www.mucommander.com
003 * Copyright (C) 2002-2008 Maxence Bernard
004 *
005 * muCommander is free software; you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation; either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * muCommander is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program. If not, see <http://www.gnu.org/licenses/>.
017 */
018
019 package com.mucommander.file.icon;
020
021 import com.mucommander.cache.LRUCache;
022 import com.mucommander.file.AbstractFile;
023
024 import javax.swing.*;
025 import java.awt.*;
026
027 /**
028 * <code>CachedFileIconProvider</code> is a <code>FileIconProvider</code> with caching capabilities.
029 *
030 * <p>This class does not actually provide icons nor does it manage the contents of the cache ; it delegates these tasks
031 * to a {@link CacheableFileIconProvider} instance. All this class does is use the cache implementation to harness its
032 * befinits and take all the credit for it.</br>
033 * When an icon is requested, a cache lookup is performed. If a cached value is found, it is returned. If not, the icon
034 * is fetched from the underlying provider and added to the cache.</p>
035 *
036 * @author Maxence Bernard
037 */
038 public class CachedFileIconProvider implements FileIconProvider {
039
040 /** The underlying icon provider and cache manager */
041 protected CacheableFileIconProvider cacheableFip;
042
043 /** Default capacity of icon caches */
044 public final static int DEFAULT_FILE_CACHE_CAPACITY = 100;
045
046 /** Current capacity of icon caches */
047 protected static int cacheCapacity = DEFAULT_FILE_CACHE_CAPACITY;
048
049
050 /**
051 * Creates a new CachedFileIconProvider that uses the given {@link CacheableFileIconProvider} to access the cache
052 * and retrieve the icons.
053 *
054 * @param cacheableFip the underlying icon provider and cache manager
055 */
056 public CachedFileIconProvider(CacheableFileIconProvider cacheableFip) {
057 this.cacheableFip = cacheableFip;
058 }
059
060 /**
061 * Creates and returns an {@link com.mucommander.cache.LRUCache} instance with a capacity equal to
062 * {@link #getCacheCapacity()}.
063 *
064 * @return an LRUCache instance
065 */
066 public static LRUCache createCache() {
067 return LRUCache.createInstance(cacheCapacity);
068 }
069
070 /**
071 * Sets the capacity of the {@link LRUCache} that caches frequently accessed file instances. The more the capacity,
072 * the more frequent the cache is hit but the higher the memory usage. By default, the capacity is
073 * {@link #DEFAULT_FILE_CACHE_CAPACITY}.
074 *
075 * <p>Note that calling this method does not change the capacity of existing caches so to be effective, this method
076 * must be called before {@link #createCache()} is called.</p>
077 *
078 * @param capacity the capacity of the LRU cache that caches frequently accessed icon instances
079 * @see com.mucommander.cache.LRUCache
080 */
081 public static void setCacheCapacity(int capacity) {
082 cacheCapacity = capacity;
083 }
084
085 /**
086 * Returns the capacity of the {@link LRUCache} that caches frequently accessed icon instances. By default, the
087 * capacity is {@link #DEFAULT_FILE_CACHE_CAPACITY}.
088 *
089 * @return the capacity of the LRU cache that caches frequently accessed icon instances
090 */
091 public static int getCacheCapacity() {
092 return cacheCapacity;
093 }
094
095
096 /////////////////////////////////////
097 // FileIconProvider implementation //
098 /////////////////////////////////////
099
100 /**
101 * <i>Implementation notes</i>: this method first calls {@link CacheableFileIconProvider#isCacheable(com.mucommander.file.AbstractFile, java.awt.Dimension)}
102 * to determine if the icon cache is used.
103 *
104 * <p><b>If the file icon is cacheable</b>, {@link CacheableFileIconProvider#lookupCache(com.mucommander.file.AbstractFile, java.awt.Dimension)}
105 * is called to look for a previously cached icon. If a value is found, it is returned. If not,
106 * {@link #getFileIcon(com.mucommander.file.AbstractFile, java.awt.Dimension)} is called on the <code>CacheableFileIconProvider</code>
107 * to retrieve the icon. This icon is then added to the cache by calling
108 * {@link CacheableFileIconProvider#addToCache(com.mucommander.file.AbstractFile, javax.swing.Icon, java.awt.Dimension)}.
109 * </p>
110 *
111 * <p><b>If the file icon is not cacheable</b>, {@link #getFileIcon(com.mucommander.file.AbstractFile, java.awt.Dimension)}
112 * is simply called on the <code>CacheableFileIconProvider</code> and its value returned.</p>
113 */
114 public Icon getFileIcon(AbstractFile file, Dimension preferredResolution) {
115 Icon icon;
116 boolean isCacheable = cacheableFip.isCacheable(file, preferredResolution);
117
118 // Look for the file icon in the provider's cache
119 if(isCacheable)
120 icon = cacheableFip.lookupCache(file, preferredResolution);
121 else
122 icon = null;
123
124 // Icon is not cacheable or isn't present in the cache, retrieve it from the provider
125 if(icon==null) {
126 icon = cacheableFip.getFileIcon(file, preferredResolution);
127
128 // Cache the icon
129 if(isCacheable && icon!=null)
130 cacheableFip.addToCache(file, icon, preferredResolution);
131 }
132
133 return icon;
134 }
135 }