Source for javax.swing.ImageIcon

   1: /* ImageIcon.java --
   2:    Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package javax.swing;
  39: 
  40: import java.awt.Component;
  41: import java.awt.Graphics;
  42: import java.awt.IllegalComponentStateException;
  43: import java.awt.Image;
  44: import java.awt.MediaTracker;
  45: import java.awt.Toolkit;
  46: import java.awt.image.ImageObserver;
  47: import java.io.Serializable;
  48: import java.net.URL;
  49: import java.util.Locale;
  50: 
  51: import javax.accessibility.Accessible;
  52: import javax.accessibility.AccessibleContext;
  53: import javax.accessibility.AccessibleIcon;
  54: import javax.accessibility.AccessibleRole;
  55: import javax.accessibility.AccessibleStateSet;
  56: 
  57: /**
  58:  * An {@link Icon} implementation that is backed by an {@link Image}.
  59:  */
  60: public class ImageIcon
  61:   implements Icon, Serializable, Accessible
  62: {
  63:   /**
  64:    * Provides the accessibility features for the <code>ImageIcon</code>
  65:    * class.
  66:    */
  67:   protected class AccessibleImageIcon
  68:     extends AccessibleContext
  69:     implements AccessibleIcon, Serializable
  70:   {
  71:     private static final long serialVersionUID = 2113430526551336564L;
  72: 
  73:     /**
  74:      * Creates a new instance of <code>AccessibleImageIcon</code>.
  75:      */
  76:     protected AccessibleImageIcon()
  77:     {
  78:       // Nothing to do here.
  79:     }
  80: 
  81:     /**
  82:      * Returns the accessible role for the <code>ImageIcon</code>.
  83:      *
  84:      * @return {@link AccessibleRole#ICON}.
  85:      */
  86:     public AccessibleRole getAccessibleRole()
  87:     {
  88:       return AccessibleRole.ICON;
  89:     }
  90: 
  91:     /**
  92:      * Returns the accessible state for the <code>ImageIcon</code>.  To
  93:      * match the reference implementation, this method always returns
  94:      * <code>null</code>.
  95:      *
  96:      * @return <code>null</code>.
  97:      */
  98:     public AccessibleStateSet getAccessibleStateSet()
  99:     {
 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: }