001 /* 002 * Copyright 2002-2007 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.application.splash; 017 018 import java.awt.Component; 019 import java.awt.Dimension; 020 import java.awt.Graphics; 021 import java.awt.Image; 022 import java.awt.MediaTracker; 023 import java.awt.Toolkit; 024 import java.io.IOException; 025 import java.net.URL; 026 027 import javax.swing.JPanel; 028 029 import org.apache.commons.logging.Log; 030 import org.apache.commons.logging.LogFactory; 031 import org.springframework.core.io.Resource; 032 import org.springframework.util.Assert; 033 034 /** 035 * A lightweight splash-screen for display when a GUI application is being 036 * initialized. 037 * <p> 038 * The splash screen renders an image in a Frame. It minimizes class loading so 039 * it is displayed immediately once the application is started. 040 * 041 * @author Keith Donald 042 * @author Jan Hoskens 043 */ 044 public class SimpleSplashScreen extends AbstractSplashScreen { 045 private Image image; 046 047 private Resource imageResourcePath; 048 049 private static final Log logger = LogFactory.getLog(SimpleSplashScreen.class); 050 051 /** 052 * Creates a new uninitialized {@code SimpleSplashScreen}. 053 */ 054 public SimpleSplashScreen() { 055 // do nothing 056 } 057 058 /** 059 * Creates a new {@code SimpleSplashScreen} that will display the image at 060 * the specified location. 061 * 062 * @param imageResourcePath The location of the image file to be displayed 063 * by this splash screen. 064 * 065 * @see #setImageResourcePath(String) 066 */ 067 public SimpleSplashScreen(Resource imageResourcePath) { 068 setImageResourcePath(imageResourcePath); 069 } 070 071 /** 072 * Creates a new {@code SimpleSplashScreen} that will display the given 073 * image. 074 * 075 * @param image the image to splash. 076 * 077 * @throws IllegalArgumentException if {@code image} is null. 078 */ 079 public SimpleSplashScreen(Image image) { 080 Assert.notNull(image, "The splash screen image is required"); 081 this.image = image; 082 } 083 084 /** 085 * Sets the location of the image to be displayed by this splash screen. If 086 * the given path starts with a '/', it is interpreted to be relative to the 087 * root of the runtime classpath. Otherwise it is interpreted to be relative 088 * to the subdirectory of the classpath root that corresponds to the package 089 * of this class. 090 * 091 * @param path The path to the splash screen image. 092 */ 093 public void setImageResourcePath(Resource path) { 094 Assert.notNull(path, "The splash screen image resource path is required"); 095 this.imageResourcePath = path; 096 } 097 098 /** 099 * Load image from path. 100 * 101 * @param path Path to image. 102 * @return Image 103 * @throws IOException 104 * 105 * @throws NullPointerException if {@code path} is null. 106 */ 107 private Image loadImage(Resource path) throws IOException { 108 URL url = path.getURL(); 109 if (url == null) { 110 logger.warn("Unable to locate splash screen in classpath at: " + path); 111 return null; 112 } 113 return Toolkit.getDefaultToolkit().createImage(url); 114 } 115 116 protected Image getImage() { 117 if (image == null && imageResourcePath != null) { 118 try { 119 image = loadImage(imageResourcePath); 120 } 121 catch (IOException e) { 122 logger.error("Unable to load image from resource " + imageResourcePath, e); 123 } 124 } 125 return image; 126 } 127 128 /** 129 * Simple Canvas that paints an image. 130 */ 131 public class ImageCanvas extends JPanel { 132 private static final long serialVersionUID = -5096223464173393949L; 133 134 private Image image; 135 136 /** 137 * Creates a new {@code ImageCanvas} with the specified image. The size 138 * of the canvas will be set to the size of the image. 139 * 140 * @param image The image to be displayed by the canvas. 141 * 142 * @throws NullPointerException if {@code image} is null. 143 */ 144 public ImageCanvas(Image image) { 145 this.image = image; 146 147 loadImage(); 148 149 Dimension size = new Dimension(image.getWidth(null), image.getHeight(null)); 150 151 setSize(size); 152 setPreferredSize(size); 153 setMinimumSize(size); 154 } 155 156 private void loadImage() { 157 MediaTracker mediaTracker = new MediaTracker(this); 158 mediaTracker.addImage(image, 0); 159 try { 160 mediaTracker.waitForID(0); 161 } 162 catch (InterruptedException e) { 163 logger.warn("Interrupted while waiting for splash image to load.", e); 164 } 165 } 166 167 public void paintComponent(Graphics g) { 168 g.clearRect(0, 0, getWidth(), getHeight()); 169 g.drawImage(image, 0, 0, this); 170 } 171 } 172 173 /** 174 * Returns a component that displays an image in a canvas. 175 */ 176 protected Component createContentPane() { 177 Image image = getImage(); 178 if (image != null) { 179 return new ImageCanvas(image); 180 } 181 return null; 182 } 183 }