001 /* ImageIcon.java --
002 Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038 package javax.swing;
039
040 import java.awt.Component;
041 import java.awt.Graphics;
042 import java.awt.IllegalComponentStateException;
043 import java.awt.Image;
044 import java.awt.MediaTracker;
045 import java.awt.Toolkit;
046 import java.awt.image.ImageObserver;
047 import java.io.Serializable;
048 import java.net.URL;
049 import java.util.Locale;
050
051 import javax.accessibility.Accessible;
052 import javax.accessibility.AccessibleContext;
053 import javax.accessibility.AccessibleIcon;
054 import javax.accessibility.AccessibleRole;
055 import javax.accessibility.AccessibleStateSet;
056
057 /**
058 * An {@link Icon} implementation that is backed by an {@link Image}.
059 */
060 public class ImageIcon
061 implements Icon, Serializable, Accessible
062 {
063 /**
064 * Provides the accessibility features for the <code>ImageIcon</code>
065 * class.
066 */
067 protected class AccessibleImageIcon
068 extends AccessibleContext
069 implements AccessibleIcon, Serializable
070 {
071 private static final long serialVersionUID = 2113430526551336564L;
072
073 /**
074 * Creates a new instance of <code>AccessibleImageIcon</code>.
075 */
076 protected AccessibleImageIcon()
077 {
078 // Nothing to do here.
079 }
080
081 /**
082 * Returns the accessible role for the <code>ImageIcon</code>.
083 *
084 * @return {@link AccessibleRole#ICON}.
085 */
086 public AccessibleRole getAccessibleRole()
087 {
088 return AccessibleRole.ICON;
089 }
090
091 /**
092 * Returns the accessible state for the <code>ImageIcon</code>. To
093 * match the reference implementation, this method always returns
094 * <code>null</code>.
095 *
096 * @return <code>null</code>.
097 */
098 public AccessibleStateSet getAccessibleStateSet()
099 {
100 // refer to Sun's bug report 4269253
101 return null;
102 }
103
104 /**
105 * Returns the accessible parent of this object. To match the reference
106 * implementation, this method always returns <code>null</code>.
107 *
108 * @return <code>null</code>.
109 */
110 public Accessible getAccessibleParent()
111 {
112 // refer to Sun's bug report 4269253
113 return null;
114 }
115
116 /**
117 * Returns the index of this object in its accessible parent. To match
118 * the reference implementation, this method always returns <code>-1</code>.
119 *
120 * @return <code>-1</code>.
121 */
122 public int getAccessibleIndexInParent()
123 {
124 // refer to Sun's bug report 4269253
125 return -1;
126 }
127
128 /**
129 * Returns the number of accessible children of this component,
130 * which is 0, because an {@link ImageIcon} has no children.
131 *
132 * @return <code>0</code>.
133 */
134 public int getAccessibleChildrenCount()
135 {
136 return 0;
137 }
138
139 /**
140 * Returns the accessible child at index <code>i</code>, which is
141 * <code>null</code> in this case because an {@link ImageIcon} has no
142 * children.
143 *
144 * @param i the index of the child to be fetched
145 *
146 * @return <code>null</code>.
147 */
148 public Accessible getAccessibleChild(int i)
149 {
150 return null;
151 }
152
153 /**
154 * Returns the locale of this object. To match the reference
155 * implementation, this method always returns <code>null</code>.
156 *
157 * @return <code>null</code>.
158 */
159 public Locale getLocale()
160 throws IllegalComponentStateException
161 {
162 // refer to Sun's bug report 4269253
163 return null;
164 }
165
166 /**
167 * Returns the accessible icon description. This returns the
168 * <code>description</code> property of the underlying {@link ImageIcon}.
169 *
170 * @return The description (possibly <code>null</code>).
171 *
172 * @see #setAccessibleIconDescription(String)
173 */
174 public String getAccessibleIconDescription()
175 {
176 return getDescription();
177 }
178
179 /**
180 * Sets the accessible icon description. This sets the
181 * <code>description</code> property of the underlying {@link ImageIcon}.
182 *
183 * @param newDescr the description (<code>null</code> permitted).
184 *
185 * @see #getAccessibleIconDescription()
186 */
187 public void setAccessibleIconDescription(String newDescr)
188 {
189 setDescription(newDescr);
190 }
191
192 /**
193 * Returns the icon height. This returns the <code>iconHeight</code>
194 * property of the underlying {@link ImageIcon}.
195 *
196 * @return The icon height.
197 */
198 public int getAccessibleIconHeight()
199 {
200 return getIconHeight();
201 }
202
203 /**
204 * Returns the icon width. This returns the <code>iconWidth</code> property
205 * of the underlying {@link ImageIcon}.
206 *
207 * @return The icon width.
208 */
209 public int getAccessibleIconWidth()
210 {
211 return getIconWidth();
212 }
213 } // AccessibleIcon
214
215 private static final long serialVersionUID = 532615968316031794L;
216
217 /** A dummy Component that is used in the MediaTracker. */
218 protected static final Component component = new Component()
219 {
220 // No need to implement this.
221 };
222
223 /** The MediaTracker used to monitor the loading of images. */
224 protected static final MediaTracker tracker = new MediaTracker(component);
225
226 /** The ID that is used in the tracker. */
227 private static int id;
228
229 Image image;
230 String description;
231 ImageObserver observer;
232
233 /** The image loading status. */
234 private int loadStatus;
235
236 /** The AccessibleContext of this ImageIcon. */
237 private AccessibleContext accessibleContext;
238
239 /**
240 * Creates an ImageIcon without any properties set.
241 */
242 public ImageIcon()
243 {
244 // Nothing to do here.
245 }
246
247 /**
248 * Constructs an ImageIcon given a filename. The icon's description
249 * is initially set to the filename itself. A filename of "" means
250 * create a blank icon.
251 *
252 * @param filename name of file to load or "" for a blank icon
253 */
254 public ImageIcon(String filename)
255 {
256 this(filename, filename);
257 }
258
259 /**
260 * Constructs an ImageIcon from the given filename, setting its
261 * description to the given description. A filename of "" means
262 * create a blank icon.
263 *
264 * @param filename name of file to load or "" for a blank icon
265 * @param description human-readable description of this icon
266 */
267 public ImageIcon(String filename, String description)
268 {
269 this(Toolkit.getDefaultToolkit().getImage(filename), description);
270 }
271
272 /**
273 * Creates an ImageIcon from the given byte array without any
274 * description set.
275 */
276 public ImageIcon(byte[] imageData)
277 {
278 this(imageData, null);
279 }
280
281 /**
282 * Creates an ImageIcon from the given byte array and sets the given
283 * description.
284 */
285 public ImageIcon(byte[] imageData, String description)
286 {
287 this(Toolkit.getDefaultToolkit().createImage(imageData), description);
288 }
289
290 /**
291 * Creates an ImageIcon from the given URL and sets the description
292 * to the URL String representation.
293 */
294 public ImageIcon(URL url)
295 {
296 this(url, url.toString());
297 }
298
299 /**
300 * Creates an ImageIcon from the given URL and sets the given
301 * description.
302 */
303 public ImageIcon(URL url, String description)
304 {
305 this(Toolkit.getDefaultToolkit().getImage(url), description);
306 }
307
308 /**
309 * Creates an ImageIcon from the given Image without any description
310 * set.
311 */
312 public ImageIcon(Image image)
313 {
314 this(image, null);
315 }
316
317 /**
318 * Creates an ImageIcon from the given Image and sets the given
319 * description.
320 */
321 public ImageIcon(Image image, String description)
322 {
323 setImage(image);
324 setDescription(description);
325 }
326
327 /**
328 * Returns the ImageObserver that is used for all Image
329 * operations. Defaults to null when not explicitly set.
330 */
331 public ImageObserver getImageObserver()
332 {
333 return observer;
334 }
335
336 /**
337 * Sets the ImageObserver that will be used for all Image
338 * operations. Can be set to null (the default) when no observer is
339 * needed.
340 */
341 public void setImageObserver(ImageObserver newObserver)
342 {
343 observer = newObserver;
344 }
345
346 /**
347 * Returns the backing Image for this ImageIcon. Might be set to
348 * null in which case no image is shown.
349 */
350 public Image getImage()
351 {
352 return image;
353 }
354
355 /**
356 * Explicitly sets the backing Image for this ImageIcon. Will call
357 * loadImage() to make sure that the Image is completely loaded
358 * before returning.
359 */
360 public void setImage(Image image)
361 {
362 loadImage(image);
363 this.image = image;
364 }
365
366 /**
367 * Returns a human readable description for this ImageIcon or null
368 * when no description is set or available.
369 */
370 public String getDescription()
371 {
372 return description;
373 }
374
375 /**
376 * Sets a human readable description for this ImageIcon. Can be set
377 * to null when no description is available.
378 */
379 public void setDescription(String description)
380 {
381 this.description = description;
382 }
383
384 /**
385 * Returns the the height of the backing Image, or -1 if the backing
386 * Image is null. The getHeight() method of the Image will be called
387 * with the set observer of this ImageIcon.
388 */
389 public int getIconHeight()
390 {
391 if (image == null)
392 return -1;
393
394 return image.getHeight(observer);
395 }
396
397 /**
398 * Returns the the width of the backing Image, or -1 if the backing
399 * Image is null. The getWidth() method of the Image will be called
400 * with the set observer of this ImageIcon.
401 */
402 public int getIconWidth()
403 {
404 if (image == null)
405 return -1;
406
407 return image.getWidth(observer);
408 }
409
410 /**
411 * Calls <code>g.drawImage()</code> on the backing Image using the
412 * set observer of this ImageIcon. If the set observer is null, the
413 * given Component is used as observer.
414 */
415 public void paintIcon(Component c, Graphics g, int x, int y)
416 {
417 g.drawImage(image, x, y, observer != null ? observer : c);
418 }
419
420 /**
421 * Loads the image and blocks until the loading operation is finished.
422 *
423 * @param image the image to be loaded
424 */
425 protected void loadImage(Image image)
426 {
427 try
428 {
429 tracker.addImage(image, id);
430 id++;
431 tracker.waitForID(id - 1);
432 }
433 catch (InterruptedException ex)
434 {
435 // Ignore this for now.
436 }
437 finally
438 {
439 loadStatus = tracker.statusID(id - 1, false);
440 tracker.removeImage(image, id - 1);
441 }
442 }
443
444 /**
445 * Returns the load status of the icon image.
446 *
447 * @return the load status of the icon image
448 *
449 * @see MediaTracker#COMPLETE
450 * @see MediaTracker#ABORTED
451 * @see MediaTracker#ERRORED
452 */
453 public int getImageLoadStatus()
454 {
455 return loadStatus;
456 }
457
458 /**
459 * Returns the object that provides accessibility features for this
460 * <code>ImageIcon</code> instance.
461 *
462 * @return The accessible context (an instance of
463 * {@link AccessibleImageIcon}).
464 */
465 public AccessibleContext getAccessibleContext()
466 {
467 if (accessibleContext == null)
468 accessibleContext = new AccessibleImageIcon();
469 return accessibleContext;
470 }
471 }