< prev index next >

src/java.desktop/share/classes/java/awt/MediaTracker.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt;
  27 
  28 import java.awt.Component;
  29 import java.awt.Image;
  30 import java.awt.image.ImageObserver;

  31 import sun.awt.image.MultiResolutionToolkitImage;


  32 
  33 /**
  34  * The {@code MediaTracker} class is a utility class to track
  35  * the status of a number of media objects. Media objects could
  36  * include audio clips as well as images, though currently only
  37  * images are supported.
  38  * <p>
  39  * To use a media tracker, create an instance of
  40  * {@code MediaTracker} and call its {@code addImage}
  41  * method for each image to be tracked. In addition, each image can
  42  * be assigned a unique identifier. This identifier controls the
  43  * priority order in which the images are fetched. It can also be used
  44  * to identify unique subsets of the images that can be waited on
  45  * independently. Images with a lower ID are loaded in preference to
  46  * those with a higher ID number.
  47  *
  48  * <p>
  49  *
  50  * Tracking an animated image
  51  * might not always be useful


 207      * (unscaled) size.
 208      * @param     image   the image to be tracked
 209      * @param     id      an identifier used to track this image
 210      */
 211     public void addImage(Image image, int id) {
 212         addImage(image, id, -1, -1);
 213     }
 214 
 215     /**
 216      * Adds a scaled image to the list of images being tracked
 217      * by this media tracker. The image will eventually be
 218      * rendered at the indicated width and height.
 219      *
 220      * @param     image   the image to be tracked
 221      * @param     id   an identifier that can be used to track this image
 222      * @param     w    the width at which the image is rendered
 223      * @param     h    the height at which the image is rendered
 224      */
 225     public synchronized void addImage(Image image, int id, int w, int h) {
 226         addImageImpl(image, id, w, h);
 227         Image rvImage = getResolutionVariant(image);
 228         if (rvImage != null) {
 229             addImageImpl(rvImage, id,
 230                     w == -1 ? -1 : 2 * w,
 231                     h == -1 ? -1 : 2 * h);









 232         }



 233     }
 234 
 235     private void addImageImpl(Image image, int id, int w, int h) {
 236         head = MediaEntry.insert(head,
 237                                  new ImageMediaEntry(this, image, id, w, h));
 238     }
 239     /**
 240      * Flag indicating that media is currently being loaded.
 241      * @see         java.awt.MediaTracker#statusAll
 242      * @see         java.awt.MediaTracker#statusID
 243      */
 244     public static final int LOADING = 1;
 245 
 246     /**
 247      * Flag indicating that the downloading of media was aborted.
 248      * @see         java.awt.MediaTracker#statusAll
 249      * @see         java.awt.MediaTracker#statusID
 250      */
 251     public static final int ABORTED = 2;
 252 


 715         while (cur != null) {
 716             if (cur.getID() == id) {
 717                 status = status | cur.getStatus(load, verify);
 718             }
 719             cur = cur.next;
 720         }
 721         return status;
 722     }
 723 
 724     /**
 725      * Removes the specified image from this media tracker.
 726      * All instances of the specified image are removed,
 727      * regardless of scale or ID.
 728      * @param   image     the image to be removed
 729      * @see     java.awt.MediaTracker#removeImage(java.awt.Image, int)
 730      * @see     java.awt.MediaTracker#removeImage(java.awt.Image, int, int, int)
 731      * @since   1.1
 732      */
 733     public synchronized void removeImage(Image image) {
 734         removeImageImpl(image);
 735         Image rvImage = getResolutionVariant(image);
 736         if (rvImage != null) {
 737             removeImageImpl(rvImage);
 738         }

 739         notifyAll();    // Notify in case remaining images are "done".
 740     }
 741 
 742     private void removeImageImpl(Image image) {
 743         MediaEntry cur = head;
 744         MediaEntry prev = null;
 745         while (cur != null) {
 746             MediaEntry next = cur.next;
 747             if (cur.getMedia() == image) {
 748                 if (prev == null) {
 749                     head = next;
 750                 } else {
 751                     prev.next = next;
 752                 }
 753                 cur.cancel();
 754             } else {
 755                 prev = cur;
 756             }
 757             cur = next;
 758         }
 759     }
 760 
 761     /**
 762      * Removes the specified image from the specified tracking
 763      * ID of this media tracker.
 764      * All instances of {@code Image} being tracked
 765      * under the specified ID are removed regardless of scale.
 766      * @param      image the image to be removed
 767      * @param      id the tracking ID from which to remove the image
 768      * @see        java.awt.MediaTracker#removeImage(java.awt.Image)
 769      * @see        java.awt.MediaTracker#removeImage(java.awt.Image, int, int, int)
 770      * @since      1.1
 771      */
 772     public synchronized void removeImage(Image image, int id) {
 773         removeImageImpl(image, id);
 774         Image rvImage = getResolutionVariant(image);
 775         if (rvImage != null) {
 776             removeImageImpl(rvImage, id);

 777         }
 778         notifyAll();    // Notify in case remaining images are "done".
 779     }
 780 
 781     private void removeImageImpl(Image image, int id) {
 782         MediaEntry cur = head;
 783         MediaEntry prev = null;
 784         while (cur != null) {
 785             MediaEntry next = cur.next;
 786             if (cur.getID() == id && cur.getMedia() == image) {
 787                 if (prev == null) {
 788                     head = next;
 789                 } else {
 790                     prev.next = next;
 791                 }
 792                 cur.cancel();
 793             } else {
 794                 prev = cur;
 795             }
 796             cur = next;
 797         }
 798     }
 799 
 800     /**
 801      * Removes the specified image with the specified
 802      * width, height, and ID from this media tracker.
 803      * Only the specified instance (with any duplicates) is removed.
 804      * @param   image the image to be removed
 805      * @param   id the tracking ID from which to remove the image
 806      * @param   width the width to remove (-1 for unscaled)
 807      * @param   height the height to remove (-1 for unscaled)
 808      * @see     java.awt.MediaTracker#removeImage(java.awt.Image)
 809      * @see     java.awt.MediaTracker#removeImage(java.awt.Image, int)
 810      * @since   1.1
 811      */
 812     public synchronized void removeImage(Image image, int id,
 813                                          int width, int height) {
 814         removeImageImpl(image, id, width, height);
 815         Image rvImage = getResolutionVariant(image);
 816         if (rvImage != null) {
 817             removeImageImpl(rvImage, id,
 818                     width == -1 ? -1 : 2 * width,
 819                     height == -1 ? -1 : 2 * height);



 820         }
 821         notifyAll();    // Notify in case remaining images are "done".
 822     }
 823 
 824     private void removeImageImpl(Image image, int id, int width, int height) {
 825         MediaEntry cur = head;
 826         MediaEntry prev = null;
 827         while (cur != null) {
 828             MediaEntry next = cur.next;
 829             if (cur.getID() == id && cur instanceof ImageMediaEntry
 830                 && ((ImageMediaEntry) cur).matches(image, width, height))
 831             {
 832                 if (prev == null) {
 833                     head = next;
 834                 } else {
 835                     prev.next = next;
 836                 }
 837                 cur.cancel();
 838             } else {
 839                 prev = cur;
 840             }
 841             cur = next;
 842         }
 843     }
 844 
 845     synchronized void setDone() {
 846         notifyAll();
 847     }
 848 
 849     private static Image getResolutionVariant(Image image) {
 850         if (image instanceof MultiResolutionToolkitImage) {
 851             return ((MultiResolutionToolkitImage) image).getResolutionVariant();
 852         }
 853         return null;
 854     }
 855 }
 856 
 857 abstract class MediaEntry {
 858     MediaTracker tracker;
 859     int ID;
 860     MediaEntry next;
 861 
 862     int status;
 863     boolean cancelled;
 864 
 865     MediaEntry(MediaTracker mt, int id) {
 866         tracker = mt;
 867         ID = id;
 868     }
 869 
 870     abstract Object getMedia();
 871 
 872     static MediaEntry insert(MediaEntry head, MediaEntry me) {
 873         MediaEntry cur = head;
 874         MediaEntry prev = null;




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt;
  27 


  28 import java.awt.image.ImageObserver;
  29 import java.awt.image.ResolutionVariantItem;
  30 import sun.awt.image.MultiResolutionToolkitImage;
  31 import java.util.List;
  32 import java.util.stream.Stream;
  33 
  34 /**
  35  * The {@code MediaTracker} class is a utility class to track
  36  * the status of a number of media objects. Media objects could
  37  * include audio clips as well as images, though currently only
  38  * images are supported.
  39  * <p>
  40  * To use a media tracker, create an instance of
  41  * {@code MediaTracker} and call its {@code addImage}
  42  * method for each image to be tracked. In addition, each image can
  43  * be assigned a unique identifier. This identifier controls the
  44  * priority order in which the images are fetched. It can also be used
  45  * to identify unique subsets of the images that can be waited on
  46  * independently. Images with a lower ID are loaded in preference to
  47  * those with a higher ID number.
  48  *
  49  * <p>
  50  *
  51  * Tracking an animated image
  52  * might not always be useful


 208      * (unscaled) size.
 209      * @param     image   the image to be tracked
 210      * @param     id      an identifier used to track this image
 211      */
 212     public void addImage(Image image, int id) {
 213         addImage(image, id, -1, -1);
 214     }
 215 
 216     /**
 217      * Adds a scaled image to the list of images being tracked
 218      * by this media tracker. The image will eventually be
 219      * rendered at the indicated width and height.
 220      *
 221      * @param     image   the image to be tracked
 222      * @param     id   an identifier that can be used to track this image
 223      * @param     w    the width at which the image is rendered
 224      * @param     h    the height at which the image is rendered
 225      */
 226     public synchronized void addImage(Image image, int id, int w, int h) {
 227         addImageImpl(image, id, w, h);
 228 
 229         if (image instanceof MultiResolutionToolkitImage) {
 230             getRVItems(image).forEach(rvItem ->
 231                     addImageImpl(rvItem.getValue(), id,
 232                                  scale(w, rvItem.getScaleX()),
 233                                  scale(h, rvItem.getScaleY())
 234                     ));
 235         }
 236     }
 237 
 238 
 239     private static Stream<ResolutionVariantItem<Image>> getRVItems(Image image) {
 240         return ((MultiResolutionToolkitImage) image)
 241                 .getResolutionVariantItems().stream();
 242     }
 243 
 244     private static int scale(int size, double scale) {
 245         return size == -1 ? -1 : (int) Math.floor(scale * size);
 246     }
 247 
 248     private void addImageImpl(Image image, int id, int w, int h) {
 249         head = MediaEntry.insert(head,
 250                                  new ImageMediaEntry(this, image, id, w, h));
 251     }
 252     /**
 253      * Flag indicating that media is currently being loaded.
 254      * @see         java.awt.MediaTracker#statusAll
 255      * @see         java.awt.MediaTracker#statusID
 256      */
 257     public static final int LOADING = 1;
 258 
 259     /**
 260      * Flag indicating that the downloading of media was aborted.
 261      * @see         java.awt.MediaTracker#statusAll
 262      * @see         java.awt.MediaTracker#statusID
 263      */
 264     public static final int ABORTED = 2;
 265 


 728         while (cur != null) {
 729             if (cur.getID() == id) {
 730                 status = status | cur.getStatus(load, verify);
 731             }
 732             cur = cur.next;
 733         }
 734         return status;
 735     }
 736 
 737     /**
 738      * Removes the specified image from this media tracker.
 739      * All instances of the specified image are removed,
 740      * regardless of scale or ID.
 741      * @param   image     the image to be removed
 742      * @see     java.awt.MediaTracker#removeImage(java.awt.Image, int)
 743      * @see     java.awt.MediaTracker#removeImage(java.awt.Image, int, int, int)
 744      * @since   1.1
 745      */
 746     public synchronized void removeImage(Image image) {
 747         removeImageImpl(image);
 748         if (image instanceof MultiResolutionToolkitImage) {
 749             getRVItems(image).forEach(rvItem ->
 750                     removeImageImpl(rvItem.getValue()));
 751         }
 752 
 753         notifyAll();    // Notify in case remaining images are "done".
 754     }
 755 
 756     private void removeImageImpl(Image image) {
 757         MediaEntry cur = head;
 758         MediaEntry prev = null;
 759         while (cur != null) {
 760             MediaEntry next = cur.next;
 761             if (cur.getMedia() == image) {
 762                 if (prev == null) {
 763                     head = next;
 764                 } else {
 765                     prev.next = next;
 766                 }
 767                 cur.cancel();
 768             } else {
 769                 prev = cur;
 770             }
 771             cur = next;
 772         }
 773     }
 774 
 775     /**
 776      * Removes the specified image from the specified tracking
 777      * ID of this media tracker.
 778      * All instances of {@code Image} being tracked
 779      * under the specified ID are removed regardless of scale.
 780      * @param      image the image to be removed
 781      * @param      id the tracking ID from which to remove the image
 782      * @see        java.awt.MediaTracker#removeImage(java.awt.Image)
 783      * @see        java.awt.MediaTracker#removeImage(java.awt.Image, int, int, int)
 784      * @since      1.1
 785      */
 786     public synchronized void removeImage(Image image, int id) {
 787         removeImageImpl(image, id);
 788 
 789         if (image instanceof MultiResolutionToolkitImage) {
 790             getRVItems(image).forEach(rvItem ->
 791                     removeImageImpl(rvItem.getValue(), id));
 792         }
 793         notifyAll();    // Notify in case remaining images are "done".
 794     }
 795 
 796     private void removeImageImpl(Image image, int id) {
 797         MediaEntry cur = head;
 798         MediaEntry prev = null;
 799         while (cur != null) {
 800             MediaEntry next = cur.next;
 801             if (cur.getID() == id && cur.getMedia() == image) {
 802                 if (prev == null) {
 803                     head = next;
 804                 } else {
 805                     prev.next = next;
 806                 }
 807                 cur.cancel();
 808             } else {
 809                 prev = cur;
 810             }
 811             cur = next;
 812         }
 813     }
 814 
 815     /**
 816      * Removes the specified image with the specified
 817      * width, height, and ID from this media tracker.
 818      * Only the specified instance (with any duplicates) is removed.
 819      * @param   image the image to be removed
 820      * @param   id the tracking ID from which to remove the image
 821      * @param   width the width to remove (-1 for unscaled)
 822      * @param   height the height to remove (-1 for unscaled)
 823      * @see     java.awt.MediaTracker#removeImage(java.awt.Image)
 824      * @see     java.awt.MediaTracker#removeImage(java.awt.Image, int)
 825      * @since   1.1
 826      */
 827     public synchronized void removeImage(Image image, int id,
 828                                          int width, int height) {
 829         removeImageImpl(image, id, width, height);
 830 
 831         if (image instanceof MultiResolutionToolkitImage) {
 832 
 833             getRVItems(image).forEach(rvItem ->
 834                     removeImageImpl(rvItem.getValue(), id,
 835                                     scale(width, rvItem.getScaleX()),
 836                                     scale(height, rvItem.getScaleY())
 837                     ));
 838         }
 839         notifyAll();    // Notify in case remaining images are "done".
 840     }
 841 
 842     private void removeImageImpl(Image image, int id, int width, int height) {
 843         MediaEntry cur = head;
 844         MediaEntry prev = null;
 845         while (cur != null) {
 846             MediaEntry next = cur.next;
 847             if (cur.getID() == id && cur instanceof ImageMediaEntry
 848                 && ((ImageMediaEntry) cur).matches(image, width, height))
 849             {
 850                 if (prev == null) {
 851                     head = next;
 852                 } else {
 853                     prev.next = next;
 854                 }
 855                 cur.cancel();
 856             } else {
 857                 prev = cur;
 858             }
 859             cur = next;
 860         }
 861     }
 862 
 863     synchronized void setDone() {
 864         notifyAll();
 865     }







 866 }
 867 
 868 abstract class MediaEntry {
 869     MediaTracker tracker;
 870     int ID;
 871     MediaEntry next;
 872 
 873     int status;
 874     boolean cancelled;
 875 
 876     MediaEntry(MediaTracker mt, int id) {
 877         tracker = mt;
 878         ID = id;
 879     }
 880 
 881     abstract Object getMedia();
 882 
 883     static MediaEntry insert(MediaEntry head, MediaEntry me) {
 884         MediaEntry cur = head;
 885         MediaEntry prev = null;


< prev index next >