001 /*
002 * Copyright 2002-2004 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.springframework.richclient.image;
017
018 import java.awt.Image;
019
020 import javax.swing.Icon;
021 import javax.swing.ImageIcon;
022
023 import org.apache.commons.logging.Log;
024 import org.apache.commons.logging.LogFactory;
025 import org.springframework.richclient.application.ApplicationServicesLocator;
026 import org.springframework.util.CachingMapDecorator;
027
028 /**
029 * The default implementation of ImageIconRegistry. This implementation caches
030 * all icons using soft references (TODO it just lazy loads them, but it doesn't use SoftReference).
031 * More specifically, cached icons will remain
032 * in memory unless there is a shortage of resources in the system.
033 *
034 * @author Keith Donald
035 */
036 public class DefaultIconSource implements IconSource {
037 protected static final Log logger = LogFactory.getLog(DefaultIconSource.class);
038
039 private IconCache cache;
040
041 /**
042 * Default constructor. Will obtain services dependencies from the ApplicationServices
043 * locator.
044 */
045 public DefaultIconSource() {
046 this( (ImageSource)ApplicationServicesLocator.services().getService(ImageSource.class));
047 }
048
049 /**
050 * Constructs a icon registry that loads images from the provided source.
051 *
052 * @param images
053 * the image source.
054 */
055 public DefaultIconSource(ImageSource images) {
056 this.cache = new IconCache(images);
057 }
058
059 public Icon getIcon(String key) {
060 try {
061 if (logger.isDebugEnabled()) {
062 logger.debug("Resolving icon with key '" + key + "'");
063 }
064 return (ImageIcon)cache.get(key);
065 }
066 catch (NoSuchImageResourceException e) {
067 if (logger.isInfoEnabled()) {
068 logger.info("No image resource found for icon with key '" + key + "'; returning a <null> icon.");
069 }
070 return null;
071 }
072 }
073
074 public void clear() {
075 cache.clear();
076 }
077
078 protected String doProcessImageKeyBeforeLookup(String key) {
079 // subclasses can override
080 return key;
081 }
082
083 protected IconCache cache() {
084 return cache;
085 }
086
087 /**
088 * Icon cache using soft references.
089 *
090 * @author Keith Donald
091 */
092 protected static class IconCache extends CachingMapDecorator {
093 private ImageSource images;
094
095 public IconCache(ImageSource images) {
096 super(true);
097 this.images = images;
098 }
099
100 public Object create(Object key) {
101 Image image = images.getImage((String)key);
102 return new ImageIcon(image);
103 }
104
105 public ImageSource images() {
106 return images;
107 }
108 }
109 }