1 /*
2 * Copyright 2008 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16 package org.utgenome.gwt.widget.client;
17
18 import java.util.ArrayList;
19
20 /**
21 * Provides a mechanism for deferred execution of a callback method once all specified Images are loaded.
22 */
23 public class ImageLoader {
24
25 /**
26 * Interface to allow anonymous instantiation of a CallBack Object with method that gets invoked when all the images
27 * are loaded.
28 */
29 public interface CallBack {
30 void onImagesLoaded(ImageHandle[] imageHandles);
31 }
32
33 /**
34 * Static internal collection of ImageLoader instances. ImageLoader is not instantiable externally.
35 */
36 private static ArrayList<ImageLoader> imageLoaders = new ArrayList<ImageLoader>();
37
38 /**
39 * Takes in an array of url Strings corresponding to the images needed to be loaded. The onImagesLoaded() method in
40 * the specified CallBack object is invoked with an array of ImageHandles corresponding to the original input array
41 * of url Strings once all the images report an onload event.
42 *
43 * @param urls
44 * Array of urls for the images that need to be loaded
45 * @param cb
46 * CallBack object
47 */
48 public static void loadImages(String[] urls, CallBack cb) {
49 ImageLoader il = new ImageLoader();
50 for (int i = 0; i < urls.length; i++) {
51 il.addHandle(il.loadImage(urls[0]));
52 }
53 il.finalize(cb);
54 ImageLoader.imageLoaders.add(il);
55 }
56
57 private CallBack callBack = null;
58 private ArrayList<ImageHandle> images = new ArrayList<ImageHandle>();
59 private int loadedImages = 0;
60 private int totalImages = 0;
61
62 private ImageLoader() {
63 }
64
65 /**
66 * Stores the ImageHandle reference so that when all the images report an onload, we can return the array of all the
67 * ImageHandles.
68 *
69 * @param img
70 */
71 private void addHandle(ImageHandle img) {
72 this.totalImages++;
73 this.images.add(img);
74 }
75
76 /**
77 * Invokes the onImagesLoaded method in the CallBack if all the images are loaded AND we have a CallBack specified.
78 *
79 * Called from the JSNI onload event handler.
80 */
81 private void dispatchIfComplete() {
82 if (callBack != null && isAllLoaded()) {
83 callBack.onImagesLoaded((ImageHandle[]) images.toArray(new ImageHandle[0]));
84 // remove the image loader
85 ImageLoader.imageLoaders.remove(this);
86 }
87 }
88
89 /**
90 * Sets the callback object for the ImageLoader. Once this is set, we may invoke the callback once all images that
91 * need to be loaded report in from their onload event handlers.
92 *
93 * @param cb
94 */
95 private void finalize(CallBack cb) {
96 this.callBack = cb;
97 }
98
99 private void incrementLoadedImages() {
100 this.loadedImages++;
101 }
102
103 private boolean isAllLoaded() {
104 return (loadedImages == totalImages);
105 }
106
107 /**
108 * Returns a handle to an img object. Ties back to the ImageLoader instance
109 */
110 private native ImageHandle loadImage(String url)/*-{
111 // if( callback specified )
112 // do nothing
113
114 var img = new Image();
115 var __this = this;
116
117 img.onload = function() {
118 if(!img.__isLoaded) {
119
120 // __isLoaded should be set for the first time here.
121 // if for some reason img fires a second onload event
122 // we do not want to execute the following again (hence the guard)
123 img.__isLoaded = true;
124 __this.@org.utgenome.gwt.widget.client.ImageLoader::incrementLoadedImages()();
125 img.onload = null;
126
127 // we call this function each time onload fires
128 // It will see if we are ready to invoke the callback
129 __this.@org.utgenome.gwt.widget.client.ImageLoader::dispatchIfComplete()();
130 }
131 }
132
133 img.src = url;
134
135 return img;
136 }-*/;
137 }