1 /** 2 * The utillib library. 3 * More information is available at http://www.jinchess.com/. 4 * Copyright (C) 2002 Alexander Maryanovsky. 5 * All rights reserved. 6 * 7 * The utillib library is free software; you can redistribute 8 * it and/or modify it under the terms of the GNU Lesser General Public License 9 * as published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * The utillib library is distributed in the hope that it will 13 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with utillib library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 package free.util; 23 24 import java.awt.Image; 25 import java.awt.Toolkit; 26 import java.awt.image.ImageObserver; 27 28 29 /** 30 * Various image related utilities. 31 */ 32 33 public class ImageUtilities{ 34 35 36 37 /** 38 * A constant indicating that the loading of the image completed. 39 */ 40 41 public static final int COMPLETE = 1; 42 43 44 45 /** 46 * A constant indicating that the loading of the image errored. 47 */ 48 49 public static final int ERRORED = 2; 50 51 52 53 /** 54 * A constant indicating that the loading of the image was aborted. 55 */ 56 57 public static final int ABORTED = 3; 58 59 60 61 /** 62 * A constant indicating that the loading of the image was interrupted. 63 */ 64 65 public static final int INTERRUPTED = 4; 66 67 68 69 /** 70 * Starts loading the given image, returns only when it's done loading. 71 * Note that it's much more efficient to preload a lot of images at once using 72 * the preload(Image []) method instead of this one. 73 * 74 * @return The result of the image loading, either {@link #COMPLETE}, 75 * {@link #ERRORED}, {@link #ABORTED} or {@link #INTERRUPTED}. 76 * 77 * @see #preload(java.awt.Image [], int []) 78 */ 79 preload(Image image)80 public static int preload(Image image){ 81 Toolkit toolkit = Toolkit.getDefaultToolkit(); 82 83 // Check if already loaded 84 if ((toolkit.checkImage(image, -1, -1, null) & ImageObserver.ALLBITS) != 0) 85 return COMPLETE; 86 87 Object lock = new Object(); 88 synchronized(lock){ 89 while (true){ 90 ImageLoadObserver observer = new ImageLoadObserver(lock); 91 toolkit.prepareImage(image, -1, -1, observer); 92 int result = toolkit.checkImage(image, -1, -1, null); 93 if ((result & ImageObserver.ALLBITS) != 0) 94 return COMPLETE; 95 if ((result & ImageObserver.ERROR) != 0) 96 return ERRORED; 97 if ((result & ImageObserver.ABORT) != 0) 98 return ABORTED; 99 100 try{ 101 lock.wait(); 102 return observer.getResult(); 103 } catch (InterruptedException e){ 104 return INTERRUPTED; 105 } 106 } 107 } 108 } 109 110 111 112 /** 113 * Starts loading the given images, returns only when all the images are done 114 * loading. If you just need to preload one Image, use the preload(Image) method 115 * instead. 116 * 117 * @return An array specifying the loading result of each image. Possible values 118 * are {@link #COMPLETE}, {@link #ERRORED} and {@link #ABORTED}. 119 * 120 * @see #preload(Image) 121 */ 122 preload(Image [] images, int [] results)123 public static int [] preload(Image [] images, int [] results){ 124 Object [] locks = new Object[images.length]; 125 ImageLoadObserver [] loadObservers = new ImageLoadObserver[images.length]; 126 if ((results == null) || (results.length < images.length)) 127 results = new int[images.length]; 128 Toolkit toolkit = Toolkit.getDefaultToolkit(); 129 for (int i = 0; i < images.length; i++){ 130 locks[i] = new Object(); 131 loadObservers[i] = new ImageLoadObserver(locks[i]); 132 toolkit.prepareImage(images[i], -1, -1, loadObservers[i]); 133 } 134 135 for (int i = 0; i < images.length; i++){ 136 synchronized(locks[i]){ 137 int result = toolkit.checkImage(images[i], -1, -1, null); 138 139 if ((result & ImageObserver.ALLBITS) != 0){ 140 results[i] = COMPLETE; 141 continue; 142 } 143 if ((result & ImageObserver.ERROR) != 0){ 144 results[i] = ERRORED; 145 continue; 146 } 147 if ((result & ImageObserver.ABORT) != 0){ 148 results[i] = ABORTED; 149 continue; 150 } 151 152 try{ 153 locks[i].wait(); 154 results[i] = loadObservers[i].getResult(); 155 } catch (InterruptedException e){ 156 results[i] = INTERRUPTED; 157 } 158 } 159 } 160 161 return results; 162 } 163 164 165 166 /** 167 * Returns whether the specified image is already fully loaded. 168 */ 169 isLoaded(Image image)170 public static boolean isLoaded(Image image){ 171 return (Toolkit.getDefaultToolkit().checkImage(image, -1, -1, null) & ImageObserver.ALLBITS) != 0; 172 } 173 174 175 176 /** 177 * This class is an implementation of ImageObserver which notifies a given 178 * lock when loading of the Image is done. This can be used to wait until a 179 * certain Image has finished loading. 180 */ 181 182 public static class ImageLoadObserver implements ImageObserver{ 183 184 185 /** 186 * The lock. 187 */ 188 189 private final Object lock; 190 191 192 193 /** 194 * The loading result. 195 */ 196 197 private int result = -1; 198 199 200 201 202 /** 203 * Creates a new ImageLoadObserver which will notify the given lock when 204 * the Image is done loading. 205 */ 206 ImageLoadObserver(Object lock)207 public ImageLoadObserver(Object lock){ 208 this.lock = lock; 209 } 210 211 212 213 /** 214 * If infoflags has the ALLBITS flag set, notifies the lock and returns 215 * false, otherwise simply returns true. 216 */ 217 imageUpdate(Image img, int infoflags, int x, int y, int width, int height)218 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height){ 219 synchronized(lock){ 220 if ((infoflags & ALLBITS)!=0){ 221 result = ImageUtilities.COMPLETE; 222 lock.notify(); 223 return false; 224 } 225 if ((infoflags & ERROR)!=0){ 226 result = ImageUtilities.ERRORED; 227 lock.notify(); 228 return false; 229 } 230 if ((infoflags & ABORT)!=0){ 231 result = ImageUtilities.ABORTED; 232 lock.notify(); 233 return false; 234 } 235 } 236 return true; 237 } 238 239 240 241 242 /** 243 * Returns the result of the image loading process or -1 if loading hasn't finished yet. 244 * Possible values are {@link ImageUtilities#COMPLETE}, {@link ImageUtilities#ERRORED} 245 * and {@link ImageUtilities#ABORTED} 246 */ 247 getResult()248 public int getResult(){ 249 return result; 250 } 251 252 } 253 254 255 } 256