Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/swing/ImageIcon.java
38829 views
/*1* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package javax.swing;2526import java.awt.*;27import java.awt.image.*;28import java.beans.ConstructorProperties;29import java.beans.Transient;30import java.net.URL;3132import java.io.Serializable;33import java.io.ObjectOutputStream;34import java.io.ObjectInputStream;35import java.io.IOException;3637import java.util.Locale;38import javax.accessibility.*;3940import sun.awt.AppContext;41import java.lang.reflect.Field;42import java.security.*;4344/**45* An implementation of the Icon interface that paints Icons46* from Images. Images that are created from a URL, filename or byte array47* are preloaded using MediaTracker to monitor the loaded state48* of the image.49*50* <p>51* For further information and examples of using image icons, see52* <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/icon.html">How to Use Icons</a>53* in <em>The Java Tutorial.</em>54*55* <p>56* <strong>Warning:</strong>57* Serialized objects of this class will not be compatible with58* future Swing releases. The current serialization support is59* appropriate for short term storage or RMI between applications running60* the same version of Swing. As of 1.4, support for long term storage61* of all JavaBeans™62* has been added to the <code>java.beans</code> package.63* Please see {@link java.beans.XMLEncoder}.64*65* @author Jeff Dinkins66* @author Lynn Monsanto67*/68public class ImageIcon implements Icon, Serializable, Accessible {69/* Keep references to the filename and location so that70* alternate persistence schemes have the option to archive71* images symbolically rather than including the image data72* in the archive.73*/74transient private String filename;75transient private URL location;7677transient Image image;78transient int loadStatus = 0;79ImageObserver imageObserver;80String description = null;8182/**83* Do not use this shared component, which is used to track image loading.84* It is left for backward compatibility only.85* @deprecated since 1.886*/87@Deprecated88protected final static Component component;8990/**91* Do not use this shared media tracker, which is used to load images.92* It is left for backward compatibility only.93* @deprecated since 1.894*/95@Deprecated96protected final static MediaTracker tracker;9798static {99component = AccessController.doPrivileged(new PrivilegedAction<Component>() {100public Component run() {101try {102final Component component = createNoPermsComponent();103104// 6482575 - clear the appContext field so as not to leak it105Field appContextField =106107Component.class.getDeclaredField("appContext");108appContextField.setAccessible(true);109appContextField.set(component, null);110111return component;112} catch (Throwable e) {113// We don't care about component.114// So don't prevent class initialisation.115e.printStackTrace();116return null;117}118}119});120tracker = new MediaTracker(component);121}122123private static Component createNoPermsComponent() {124// 7020198 - set acc field to no permissions and no subject125// Note, will have appContext set.126return AccessController.doPrivileged(127new PrivilegedAction<Component>() {128public Component run() {129return new Component() {130};131}132},133new AccessControlContext(new ProtectionDomain[]{134new ProtectionDomain(null, null)135})136);137}138139/**140* Id used in loading images from MediaTracker.141*/142private static int mediaTrackerID;143144private final static Object TRACKER_KEY = new StringBuilder("TRACKER_KEY");145146int width = -1;147int height = -1;148149/**150* Creates an ImageIcon from the specified file. The image will151* be preloaded by using MediaTracker to monitor the loading state152* of the image.153* @param filename the name of the file containing the image154* @param description a brief textual description of the image155* @see #ImageIcon(String)156*/157public ImageIcon(String filename, String description) {158image = Toolkit.getDefaultToolkit().getImage(filename);159if (image == null) {160return;161}162this.filename = filename;163this.description = description;164loadImage(image);165}166167/**168* Creates an ImageIcon from the specified file. The image will169* be preloaded by using MediaTracker to monitor the loading state170* of the image. The specified String can be a file name or a171* file path. When specifying a path, use the Internet-standard172* forward-slash ("/") as a separator.173* (The string is converted to an URL, so the forward-slash works174* on all systems.)175* For example, specify:176* <pre>177* new ImageIcon("images/myImage.gif") </pre>178* The description is initialized to the <code>filename</code> string.179*180* @param filename a String specifying a filename or path181* @see #getDescription182*/183@ConstructorProperties({"description"})184public ImageIcon (String filename) {185this(filename, filename);186}187188/**189* Creates an ImageIcon from the specified URL. The image will190* be preloaded by using MediaTracker to monitor the loaded state191* of the image.192* @param location the URL for the image193* @param description a brief textual description of the image194* @see #ImageIcon(String)195*/196public ImageIcon(URL location, String description) {197image = Toolkit.getDefaultToolkit().getImage(location);198if (image == null) {199return;200}201this.location = location;202this.description = description;203loadImage(image);204}205206/**207* Creates an ImageIcon from the specified URL. The image will208* be preloaded by using MediaTracker to monitor the loaded state209* of the image.210* The icon's description is initialized to be211* a string representation of the URL.212* @param location the URL for the image213* @see #getDescription214*/215public ImageIcon (URL location) {216this(location, location.toExternalForm());217}218219/**220* Creates an ImageIcon from the image.221* @param image the image222* @param description a brief textual description of the image223*/224public ImageIcon(Image image, String description) {225this(image);226this.description = description;227}228229/**230* Creates an ImageIcon from an image object.231* If the image has a "comment" property that is a string,232* then the string is used as the description of this icon.233* @param image the image234* @see #getDescription235* @see java.awt.Image#getProperty236*/237public ImageIcon (Image image) {238this.image = image;239Object o = image.getProperty("comment", imageObserver);240if (o instanceof String) {241description = (String) o;242}243loadImage(image);244}245246/**247* Creates an ImageIcon from an array of bytes which were248* read from an image file containing a supported image format,249* such as GIF, JPEG, or (as of 1.3) PNG.250* Normally this array is created251* by reading an image using Class.getResourceAsStream(), but252* the byte array may also be statically stored in a class.253*254* @param imageData an array of pixels in an image format supported255* by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG256* @param description a brief textual description of the image257* @see java.awt.Toolkit#createImage258*/259public ImageIcon (byte[] imageData, String description) {260this.image = Toolkit.getDefaultToolkit().createImage(imageData);261if (image == null) {262return;263}264this.description = description;265loadImage(image);266}267268/**269* Creates an ImageIcon from an array of bytes which were270* read from an image file containing a supported image format,271* such as GIF, JPEG, or (as of 1.3) PNG.272* Normally this array is created273* by reading an image using Class.getResourceAsStream(), but274* the byte array may also be statically stored in a class.275* If the resulting image has a "comment" property that is a string,276* then the string is used as the description of this icon.277*278* @param imageData an array of pixels in an image format supported by279* the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG280* @see java.awt.Toolkit#createImage281* @see #getDescription282* @see java.awt.Image#getProperty283*/284public ImageIcon (byte[] imageData) {285this.image = Toolkit.getDefaultToolkit().createImage(imageData);286if (image == null) {287return;288}289Object o = image.getProperty("comment", imageObserver);290if (o instanceof String) {291description = (String) o;292}293loadImage(image);294}295296/**297* Creates an uninitialized image icon.298*/299public ImageIcon() {300}301302/**303* Loads the image, returning only when the image is loaded.304* @param image the image305*/306protected void loadImage(Image image) {307MediaTracker mTracker = getTracker();308synchronized(mTracker) {309int id = getNextID();310311mTracker.addImage(image, id);312try {313mTracker.waitForID(id, 0);314} catch (InterruptedException e) {315System.out.println("INTERRUPTED while loading Image");316}317loadStatus = mTracker.statusID(id, false);318mTracker.removeImage(image, id);319320width = image.getWidth(imageObserver);321height = image.getHeight(imageObserver);322}323}324325/**326* Returns an ID to use with the MediaTracker in loading an image.327*/328private int getNextID() {329synchronized(getTracker()) {330return ++mediaTrackerID;331}332}333334/**335* Returns the MediaTracker for the current AppContext, creating a new336* MediaTracker if necessary.337*/338private MediaTracker getTracker() {339Object trackerObj;340AppContext ac = AppContext.getAppContext();341// Opt: Only synchronize if trackerObj comes back null?342// If null, synchronize, re-check for null, and put new tracker343synchronized(ac) {344trackerObj = ac.get(TRACKER_KEY);345if (trackerObj == null) {346Component comp = new Component() {};347trackerObj = new MediaTracker(comp);348ac.put(TRACKER_KEY, trackerObj);349}350}351return (MediaTracker) trackerObj;352}353354/**355* Returns the status of the image loading operation.356* @return the loading status as defined by java.awt.MediaTracker357* @see java.awt.MediaTracker#ABORTED358* @see java.awt.MediaTracker#ERRORED359* @see java.awt.MediaTracker#COMPLETE360*/361public int getImageLoadStatus() {362return loadStatus;363}364365/**366* Returns this icon's <code>Image</code>.367* @return the <code>Image</code> object for this <code>ImageIcon</code>368*/369@Transient370public Image getImage() {371return image;372}373374/**375* Sets the image displayed by this icon.376* @param image the image377*/378public void setImage(Image image) {379this.image = image;380loadImage(image);381}382383/**384* Gets the description of the image. This is meant to be a brief385* textual description of the object. For example, it might be386* presented to a blind user to give an indication of the purpose387* of the image.388* The description may be null.389*390* @return a brief textual description of the image391*/392public String getDescription() {393return description;394}395396/**397* Sets the description of the image. This is meant to be a brief398* textual description of the object. For example, it might be399* presented to a blind user to give an indication of the purpose400* of the image.401* @param description a brief textual description of the image402*/403public void setDescription(String description) {404this.description = description;405}406407/**408* Paints the icon.409* The top-left corner of the icon is drawn at410* the point (<code>x</code>, <code>y</code>)411* in the coordinate space of the graphics context <code>g</code>.412* If this icon has no image observer,413* this method uses the <code>c</code> component414* as the observer.415*416* @param c the component to be used as the observer417* if this icon has no image observer418* @param g the graphics context419* @param x the X coordinate of the icon's top-left corner420* @param y the Y coordinate of the icon's top-left corner421*/422public synchronized void paintIcon(Component c, Graphics g, int x, int y) {423if(imageObserver == null) {424g.drawImage(image, x, y, c);425} else {426g.drawImage(image, x, y, imageObserver);427}428}429430/**431* Gets the width of the icon.432*433* @return the width in pixels of this icon434*/435public int getIconWidth() {436return width;437}438439/**440* Gets the height of the icon.441*442* @return the height in pixels of this icon443*/444public int getIconHeight() {445return height;446}447448/**449* Sets the image observer for the image. Set this450* property if the ImageIcon contains an animated GIF, so451* the observer is notified to update its display.452* For example:453* <pre>454* icon = new ImageIcon(...)455* button.setIcon(icon);456* icon.setImageObserver(button);457* </pre>458*459* @param observer the image observer460*/461public void setImageObserver(ImageObserver observer) {462imageObserver = observer;463}464465/**466* Returns the image observer for the image.467*468* @return the image observer, which may be null469*/470@Transient471public ImageObserver getImageObserver() {472return imageObserver;473}474475/**476* Returns a string representation of this image.477*478* @return a string representing this image479*/480public String toString() {481if (description != null) {482return description;483}484return super.toString();485}486487private void readObject(ObjectInputStream s)488throws ClassNotFoundException, IOException489{490s.defaultReadObject();491492int w = s.readInt();493int h = s.readInt();494int[] pixels = (int[])(s.readObject());495496if (pixels != null) {497Toolkit tk = Toolkit.getDefaultToolkit();498ColorModel cm = ColorModel.getRGBdefault();499image = tk.createImage(new MemoryImageSource(w, h, cm, pixels, 0, w));500loadImage(image);501}502}503504505private void writeObject(ObjectOutputStream s)506throws IOException507{508s.defaultWriteObject();509510int w = getIconWidth();511int h = getIconHeight();512int[] pixels = image != null? new int[w * h] : null;513514if (image != null) {515try {516PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);517pg.grabPixels();518if ((pg.getStatus() & ImageObserver.ABORT) != 0) {519throw new IOException("failed to load image contents");520}521}522catch (InterruptedException e) {523throw new IOException("image load interrupted");524}525}526527s.writeInt(w);528s.writeInt(h);529s.writeObject(pixels);530}531532/**533* --- Accessibility Support ---534*/535536private AccessibleImageIcon accessibleContext = null;537538/**539* Gets the AccessibleContext associated with this ImageIcon.540* For image icons, the AccessibleContext takes the form of an541* AccessibleImageIcon.542* A new AccessibleImageIcon instance is created if necessary.543*544* @return an AccessibleImageIcon that serves as the545* AccessibleContext of this ImageIcon546* @beaninfo547* expert: true548* description: The AccessibleContext associated with this ImageIcon.549* @since 1.3550*/551public AccessibleContext getAccessibleContext() {552if (accessibleContext == null) {553accessibleContext = new AccessibleImageIcon();554}555return accessibleContext;556}557558/**559* This class implements accessibility support for the560* <code>ImageIcon</code> class. It provides an implementation of the561* Java Accessibility API appropriate to image icon user-interface562* elements.563* <p>564* <strong>Warning:</strong>565* Serialized objects of this class will not be compatible with566* future Swing releases. The current serialization support is567* appropriate for short term storage or RMI between applications running568* the same version of Swing. As of 1.4, support for long term storage569* of all JavaBeans™570* has been added to the <code>java.beans</code> package.571* Please see {@link java.beans.XMLEncoder}.572* @since 1.3573*/574protected class AccessibleImageIcon extends AccessibleContext575implements AccessibleIcon, Serializable {576577/*578* AccessibleContest implementation -----------------579*/580581/**582* Gets the role of this object.583*584* @return an instance of AccessibleRole describing the role of the585* object586* @see AccessibleRole587*/588public AccessibleRole getAccessibleRole() {589return AccessibleRole.ICON;590}591592/**593* Gets the state of this object.594*595* @return an instance of AccessibleStateSet containing the current596* state set of the object597* @see AccessibleState598*/599public AccessibleStateSet getAccessibleStateSet() {600return null;601}602603/**604* Gets the Accessible parent of this object. If the parent of this605* object implements Accessible, this method should simply return606* getParent().607*608* @return the Accessible parent of this object -- can be null if this609* object does not have an Accessible parent610*/611public Accessible getAccessibleParent() {612return null;613}614615/**616* Gets the index of this object in its accessible parent.617*618* @return the index of this object in its parent; -1 if this619* object does not have an accessible parent.620* @see #getAccessibleParent621*/622public int getAccessibleIndexInParent() {623return -1;624}625626/**627* Returns the number of accessible children in the object. If all628* of the children of this object implement Accessible, than this629* method should return the number of children of this object.630*631* @return the number of accessible children in the object.632*/633public int getAccessibleChildrenCount() {634return 0;635}636637/**638* Returns the nth Accessible child of the object.639*640* @param i zero-based index of child641* @return the nth Accessible child of the object642*/643public Accessible getAccessibleChild(int i) {644return null;645}646647/**648* Returns the locale of this object.649*650* @return the locale of this object651*/652public Locale getLocale() throws IllegalComponentStateException {653return null;654}655656/*657* AccessibleIcon implementation -----------------658*/659660/**661* Gets the description of the icon. This is meant to be a brief662* textual description of the object. For example, it might be663* presented to a blind user to give an indication of the purpose664* of the icon.665*666* @return the description of the icon667*/668public String getAccessibleIconDescription() {669return ImageIcon.this.getDescription();670}671672/**673* Sets the description of the icon. This is meant to be a brief674* textual description of the object. For example, it might be675* presented to a blind user to give an indication of the purpose676* of the icon.677*678* @param description the description of the icon679*/680public void setAccessibleIconDescription(String description) {681ImageIcon.this.setDescription(description);682}683684/**685* Gets the height of the icon.686*687* @return the height of the icon688*/689public int getAccessibleIconHeight() {690return ImageIcon.this.height;691}692693/**694* Gets the width of the icon.695*696* @return the width of the icon697*/698public int getAccessibleIconWidth() {699return ImageIcon.this.width;700}701702private void readObject(ObjectInputStream s)703throws ClassNotFoundException, IOException704{705s.defaultReadObject();706}707708private void writeObject(ObjectOutputStream s)709throws IOException710{711s.defaultWriteObject();712}713} // AccessibleImageIcon714}715716717