1 11 package org.eclipse.ui.internal.forms.widgets; 12 13 import java.io.IOException ; 14 import java.io.InputStream ; 15 import java.net.URL ; 16 17 import org.eclipse.core.runtime.FileLocator; 18 import org.eclipse.core.runtime.Path; 19 import org.eclipse.core.runtime.Platform; 20 import org.eclipse.swt.SWT; 21 import org.eclipse.swt.events.PaintEvent; 22 import org.eclipse.swt.events.PaintListener; 23 import org.eclipse.swt.graphics.GC; 24 import org.eclipse.swt.graphics.Image; 25 import org.eclipse.swt.graphics.ImageData; 26 import org.eclipse.swt.graphics.ImageLoader; 27 import org.eclipse.swt.graphics.Point; 28 import org.eclipse.swt.graphics.Rectangle; 29 import org.eclipse.swt.widgets.Canvas; 30 import org.eclipse.swt.widgets.Composite; 31 import org.eclipse.swt.widgets.Display; 32 import org.osgi.framework.Bundle; 33 34 public class BusyIndicator extends Canvas { 35 private static final int MARGIN = 0; 36 37 private ImageData[] progressData; 38 39 protected ImageLoader loader; 40 41 protected Image image; 42 43 protected Image animationImage; 44 45 protected Thread busyThread; 46 47 protected boolean stop; 48 49 57 public BusyIndicator(Composite parent, int style) { 58 super(parent, style); 59 60 loadProgressImage(); 61 62 addPaintListener(new PaintListener() { 63 public void paintControl(PaintEvent event) { 64 onPaint(event); 65 } 66 }); 67 } 68 69 private void loadProgressImage() { 70 InputStream is = null; 71 Bundle bundle = Platform.getBundle("org.eclipse.ui.forms"); URL url = FileLocator.find(bundle, new Path("$nl$/icons/progress/ani/progress.gif"),null); if (url != null) { 74 try { 75 url = FileLocator.resolve(url); 76 is = url.openStream(); 77 } catch (IOException e) { 78 is = null; 79 } 80 } 81 if (is != null) { 82 loader = new ImageLoader(); 83 try { 84 progressData = loader.load(is); 85 } catch (IllegalArgumentException e) { 86 } 87 try { 88 is.close(); 89 } catch (IOException e) { 90 } 91 } 92 } 93 94 public Point computeSize(int wHint, int hHint, boolean changed) { 95 Point size = new Point(0, 0); 96 if (image != null) { 97 Rectangle ibounds = image.getBounds(); 98 size.x = ibounds.width; 99 size.y = ibounds.height; 100 } 101 if (loader != null && isBusy()) { 102 size.x = Math.max(size.x, loader.logicalScreenWidth); 103 size.y = Math.max(size.y, loader.logicalScreenHeight); 104 } 105 size.x += MARGIN + MARGIN; 106 size.y += MARGIN + MARGIN; 107 return size; 108 } 109 110 113 protected synchronized void createBusyThread() { 114 if (busyThread != null) 115 return; 116 117 stop = false; 118 final Display display = getDisplay(); 119 final Image offScreenImage = new Image(display, 120 loader.logicalScreenWidth, 121 loader.logicalScreenHeight); 122 final GC offScreenImageGC = new GC(offScreenImage); 123 busyThread = new Thread () { 124 private Image timage; 125 126 public void run() { 127 try { 128 132 FormUtil.setAntialias(offScreenImageGC, SWT.ON); 133 display.syncExec(new Runnable () { 134 public void run() { 135 if (!isDisposed()) 136 drawBackground(offScreenImageGC, 0, 0, 137 loader.logicalScreenWidth, 138 loader.logicalScreenHeight); 139 } 140 }); 141 if (isDisposed()) 142 return; 143 144 148 int imageDataIndex = 0; 149 ImageData imageData = progressData[imageDataIndex]; 150 if (timage != null && !timage.isDisposed()) 151 timage.dispose(); 152 timage = new Image(display, imageData); 153 offScreenImageGC.drawImage(timage, 0, 0, 154 imageData.width, imageData.height, imageData.x, 155 imageData.y, imageData.width, imageData.height); 156 157 162 int repeatCount = loader.repeatCount; 163 while (loader.repeatCount == 0 || repeatCount > 0) { 164 if (stop || isDisposed()) 165 break; 166 switch (imageData.disposalMethod) { 167 case SWT.DM_FILL_BACKGROUND: 168 172 177 final ImageData fimageData = imageData; 178 display.syncExec(new Runnable () { 179 public void run() { 180 if (!isDisposed()) { 181 drawBackground(offScreenImageGC, fimageData.x, 182 fimageData.y, fimageData.width, 183 fimageData.height); 184 } 185 } 186 }); 187 break; 188 case SWT.DM_FILL_PREVIOUS: 189 190 offScreenImageGC.drawImage(timage, 0, 0, 191 imageData.width, imageData.height, 192 imageData.x, imageData.y, 193 imageData.width, imageData.height); 194 break; 195 } 196 197 imageDataIndex = (imageDataIndex + 1) 198 % progressData.length; 199 imageData = progressData[imageDataIndex]; 200 timage.dispose(); 201 timage = new Image(display, imageData); 202 offScreenImageGC.drawImage(timage, 0, 0, 203 imageData.width, imageData.height, 204 imageData.x, imageData.y, imageData.width, 205 imageData.height); 206 207 208 animationImage = offScreenImage; 209 display.syncExec(new Runnable () { 210 public void run() { 211 if (!isDisposed()) 212 redraw(); 213 } 214 }); 215 219 try { 220 int ms = imageData.delayTime * 10; 221 if (ms < 20) 222 ms += 50; 223 if (ms < 30) 224 ms += 20; 225 Thread.sleep(ms); 226 } catch (InterruptedException e) { 227 } 228 229 233 if (imageDataIndex == progressData.length - 1) 234 repeatCount--; 235 } 236 } catch (Exception e) { 237 } finally { 240 display.syncExec(new Runnable () { 241 public void run() { 242 if (offScreenImage != null 243 && !offScreenImage.isDisposed()) 244 offScreenImage.dispose(); 245 if (offScreenImageGC != null 246 && !offScreenImageGC.isDisposed()) 247 offScreenImageGC.dispose(); 248 } 249 }); 250 if (timage != null && !timage.isDisposed()) 251 timage.dispose(); 252 } 253 if (busyThread == null) 254 display.syncExec(new Runnable () { 255 public void run() { 256 animationImage = null; 257 if (!isDisposed()) 258 redraw(); 259 } 260 }); 261 } 262 }; 263 busyThread.setPriority(Thread.NORM_PRIORITY + 2); 264 busyThread.setDaemon(true); 265 busyThread.start(); 266 } 267 268 public void dispose() { 269 stop = true; 270 busyThread = null; 271 super.dispose(); 272 } 273 274 277 public Image getImage() { 278 return image; 279 } 280 281 286 public boolean isBusy() { 287 return (busyThread != null); 288 } 289 290 293 protected void onPaint(PaintEvent event) { 294 if (animationImage != null && animationImage.isDisposed()) { 295 animationImage = null; 296 } 297 Rectangle rect = getClientArea(); 298 if (rect.width == 0 || rect.height == 0) 299 return; 300 301 GC gc = event.gc; 302 Image activeImage = animationImage != null ? animationImage : image; 303 if (activeImage != null) { 304 Rectangle ibounds = activeImage.getBounds(); 305 gc.drawImage(activeImage, rect.width / 2 - ibounds.width / 2, 306 rect.height / 2 - ibounds.height / 2); 307 } 308 } 309 310 316 public synchronized void setBusy(boolean busy) { 317 if (busy) { 318 if (busyThread == null) 319 createBusyThread(); 320 } else { 321 if (busyThread != null) { 322 stop = true; 323 busyThread = null; 324 } 325 } 326 } 327 328 331 public void setImage(Image image) { 332 if (image != this.image && !isDisposed()) { 333 this.image = image; 334 redraw(); 335 } 336 } 337 } 338 | Popular Tags |