1 36 37 40 41 import java.awt.*; 42 import java.awt.event.*; 43 import java.applet.Applet ; 44 import java.applet.AudioClip ; 45 import java.util.Vector ; 46 import java.util.Hashtable ; 47 import java.util.Enumeration ; 48 import java.net.URL ; 49 import java.net.MalformedURLException ; 50 import java.util.List ; 51 import java.util.ArrayList ; 52 import java.util.Iterator ; 53 54 63 public class Animator extends Applet implements Runnable , MouseListener { 64 int appWidth = 0; int appHeight = 0; Thread engine = null; boolean userPause = false; boolean loaded = false; boolean error = false; Animation animation = null; String hrefTarget = null; URL hrefURL = null; 74 static final String sourceLocation = 75 "http://java.sun.com/applets/applets/Animator/"; 76 static final String userInstructions = "shift-click for errors, info"; 77 static final int STARTUP_ID = 0; 78 static final int BACKGROUND_ID = 1; 79 static final int ANIMATION_ID = 2; 80 81 84 public String getAppletInfo() { 85 return "Animator v1.10 (02/05/97), by Herb Jellinek"; 86 } 87 88 91 public String [][] getParameterInfo() { 92 String [][] info = { 93 {"imagesource", "URL", "a directory"}, 94 {"startup", "URL", "image displayed at start-up"}, 95 {"backgroundcolor", "int", "background color (24-bit RGB number)"}, 96 {"background", "URL", "image displayed as background"}, 97 {"startimage", "int", "index of first image"}, 98 {"endimage", "int", "index of last image"}, 99 {"namepattern", "URL", "generates indexed names"}, 100 {"images", "URLs", "list of image indices"}, 101 {"href", "URL", "page to visit on mouse-click"}, 102 {"target", "name", "frame to put that page in"}, 103 {"pause", "int", "global pause, milliseconds"}, 104 {"pauses", "ints", "individual pauses, milliseconds"}, 105 {"repeat", "boolean", "repeat? true or false"}, 106 {"positions", "coordinates", "path images will follow"}, 107 {"soundsource", "URL", "audio directory"}, 108 {"soundtrack", "URL", "background music"}, 109 {"sounds", "URLs", "list of audio samples"}, 110 }; 111 return info; 112 } 113 114 118 void showDescription() { 119 DescriptionFrame description = new DescriptionFrame(); 120 description.tell("\t\t"+getAppletInfo()+"\n"); 121 description.tell("Updates, documentation at "+sourceLocation+"\n\n"); 122 description.tell("Document base: "+getDocumentBase()+"\n"); 123 description.tell("Code base: "+getCodeBase()+"\n\n"); 124 125 Object errors[] = animation.tracker.getErrorsAny(); 126 if (errors != null) { 127 description.tell("Applet image errors:\n"); 128 for (int i = 0; i < errors.length; i++) { 129 if (errors[i] instanceof Image) { 130 AnimationFrame frame = (AnimationFrame) 131 animation.frames.get(i); 132 URL url = frame.imageLocation; 133 if (url != null) { 134 description.tell(" "+url+" not loaded\n"); 135 } 136 } 137 } 138 description.tell("\n"); 139 } 140 if (animation.frames == null || animation.frames.size() == 0) 141 description.tell("\n** No images loaded **\n\n"); 142 description.tell("Applet parameters:\n"); 143 description.tell(" width = "+getParameter("WIDTH")+"\n"); 144 description.tell(" height = "+getParameter("HEIGHT")+"\n"); 145 String params[][] = getParameterInfo(); 146 for (int i = 0; i < params.length; i++) { 147 String name = params[i][0]; 148 description.tell(" "+name+" = "+getParameter(name)+ 149 "\t ["+params[i][2]+"]\n"); 150 } 151 description.show(); 152 } 153 154 157 public String getParam(String key) { 158 String result = getParameter(key); 159 return result; 160 } 161 162 165 public void handleParams() { 166 try { 167 String param = getParam("IMAGESOURCE"); 168 animation.imageSource = (param == null) ? getDocumentBase() : 169 new URL (getDocumentBase(), param + "/"); 170 171 String href = getParam("HREF"); 172 if (href != null) { 173 try { 174 hrefURL = new URL (getDocumentBase(), href); 175 } catch (MalformedURLException e) { 176 showParseError(e); 177 } 178 } 179 180 hrefTarget = getParam("TARGET"); 181 if (hrefTarget == null) 182 hrefTarget = "_top"; 183 param = getParam("PAUSE"); 184 if (param != null) 185 animation.setGlobalPause(Integer.parseInt(param)); 186 param = getParam("REPEAT"); 187 animation.repeat = (param == null) ? true : 188 (param.equalsIgnoreCase("yes") || 189 param.equalsIgnoreCase("true")); 190 int startImage = 1; 191 int endImage = 1; 192 param = getParam("ENDIMAGE"); 193 if (param != null) { 194 endImage = Integer.parseInt(param); 195 param = getParam("STARTIMAGE"); 196 if (param != null) { 197 startImage = Integer.parseInt(param); 198 } 199 param = getParam("NAMEPATTERN"); 200 animation.prepareImageRange(startImage, endImage, param); 201 } else { 202 param = getParam("STARTIMAGE"); 203 if (param != null) { 204 startImage = Integer.parseInt(param); 205 param = getParam("NAMEPATTERN"); 206 animation.prepareImageRange(startImage, endImage, param); 207 } else { 208 param = getParam("IMAGES"); 209 if (param == null) { 210 showStatus("No legal IMAGES, STARTIMAGE, or ENDIMAGE "+ 211 "specified."); 212 error = true; 213 return; 214 } else { 215 animation.parseImages(param, getParam("NAMEPATTERN")); 216 } 217 } 218 } 219 220 param = getParam("BACKGROUND"); 221 if (param != null) 222 animation.backgroundImageURL = new URL (animation.imageSource, 223 param); 224 param = getParam("BACKGROUNDCOLOR"); 225 if (param != null) 226 animation.backgroundColor = decodeColor(param); 227 param = getParam("STARTUP"); 228 if (param != null) 229 animation.startUpImageURL = new URL (animation.imageSource, 230 param); 231 param = getParam("SOUNDSOURCE"); 232 animation.soundSource = (param == null) ? animation.imageSource : 233 new URL (getDocumentBase(), param + "/"); 234 param = getParam("SOUNDS"); 235 if (param != null) 236 animation.parseSounds(param); 237 param = getParam("PAUSES"); 238 if (param != null) 239 animation.parseDurations(param); 240 param = getParam("POSITIONS"); 241 if (param != null) 242 animation.parsePositions(param); 243 param = getParam("SOUNDTRACK"); 244 if (param != null) 245 animation.soundTrackURL = new URL ( 246 animation.soundSource, param); 247 } catch (MalformedURLException e) { 248 showParseError(e); 249 } catch (ParseException e) { 250 showParseError(e); 251 } 252 } 253 254 private Color decodeColor(String s) { 255 int val = 0; 256 try { 257 if (s.startsWith("0x")) { 258 val = Integer.parseInt(s.substring(2), 16); 259 } else if (s.startsWith("#")) { 260 val = Integer.parseInt(s.substring(1), 16); 261 } else if (s.startsWith("0") && s.length() > 1) { 262 val = Integer.parseInt(s.substring(1), 8); 263 } else { 264 val = Integer.parseInt(s, 10); 265 } 266 return new Color(val); 267 } catch (NumberFormatException e) { 268 return null; 269 } 270 } 271 272 275 public void init() { 276 appWidth = getSize().width; 278 appHeight = getSize().height; 279 animation = new Animation(this); 280 handleParams(); 281 animation.init(); 282 addMouseListener(this); 283 Thread me = Thread.currentThread(); 284 me.setPriority(Thread.MIN_PRIORITY); 285 userPause = false; 286 } 287 288 public void destroy() { 289 removeMouseListener(this); 290 } 291 292 void tellLoadingMsg(String file, String fileType) { 293 showStatus("Animator: loading "+fileType+" "+file); 294 } 295 296 void tellLoadingMsg(URL url, String fileType) { 297 tellLoadingMsg(url.toExternalForm(), fileType); 298 } 299 300 void clearLoadingMessage() { 301 showStatus(""); 302 } 303 304 void loadError(String fileName, String fileType) { 305 String errorMsg = "Animator: Couldn't load "+fileType+" "+ 306 fileName; 307 showStatus(errorMsg); 308 System.err.println(errorMsg); 309 error = true; 310 repaint(); 311 } 312 313 void loadError(URL badURL, String fileType) { 314 loadError(badURL.toExternalForm(), fileType); 315 } 316 317 void showParseError(Exception e) { 318 String errorMsg = "Animator: Parse error: "+e; 319 showStatus(errorMsg); 320 System.err.println(errorMsg); 321 error = true; 322 repaint(); 323 } 324 325 329 public void run() { 330 Thread me = Thread.currentThread(); 331 332 if (animation == null) 333 return; 334 if (animation.frames == null) 335 return; 336 if ((appWidth <= 0) || (appHeight <= 0)) 337 return; 338 339 try { 340 animation.startPlaying(); 341 342 while (engine == me) { 343 AnimationFrame thisFrame = (AnimationFrame) 345 animation.frames.get(animation.currentFrame); 346 repaint(); 347 if (thisFrame.sound != null) 348 thisFrame.sound.play(); 349 350 animation.currentFrame++; 351 if (animation.currentFrame >= animation.frames.size()) { 353 if (animation.repeat) 354 animation.currentFrame = 0; 355 else return; 356 } 357 358 try { 360 Thread.sleep(thisFrame.duration); 361 synchronized(this) { 362 while (userPause) { 363 animation.stopPlaying(); 364 wait(); 365 } 366 } 367 } catch (InterruptedException e) { 368 } 369 } 370 } finally { 371 synchronized(this) { 372 if (engine == me) 373 animation.stopPlaying(); 374 } 375 } 376 } 377 378 381 public void update(Graphics g) { 382 paint(g); 383 } 384 385 388 public void paint(Graphics g) { 389 if (error || ! loaded) { 390 if (animation.startUpImage != null) { 391 if (animation.tracker.checkID(STARTUP_ID)) { 392 if (animation.backgroundColor != null) { 393 g.setColor(animation.backgroundColor); 394 g.fillRect(0, 0, appWidth, appHeight); 395 } 396 g.drawImage(animation.startUpImage, 0, 0, this); 397 } 398 } else { 399 if ((animation.backgroundImage != null) && 400 (animation.tracker.checkID(BACKGROUND_ID))) 401 g.drawImage(animation.backgroundImage, 0, 0, this); 402 else 403 g.clearRect(0, 0, appWidth, appHeight); 404 } 405 } else { 406 animation.paint(g); 407 } 408 } 409 410 413 public void start() { 414 engine = new Thread (this); 415 engine.start(); 416 showStatus(getAppletInfo()); 417 } 418 419 422 public synchronized void stop() { 423 engine = null; 424 animation.stopPlaying(); 425 if (userPause) { 426 userPause = false; 427 notify(); 428 } 429 } 430 431 436 public synchronized void mousePressed(MouseEvent event) { 437 event.consume(); 438 if ((event.getModifiers() & InputEvent.SHIFT_MASK) != 0) { 439 showDescription(); 440 return; 441 } else if (hrefURL != null) { 442 return; 444 } else if (loaded) { 445 userPause = !userPause; 446 if (!userPause) { 447 animation.startPlaying(); 448 notifyAll(); 449 } 450 } 451 } 452 453 public void mouseClicked(MouseEvent event) { 454 if ((hrefURL != null) && 455 ((event.getModifiers() & InputEvent.SHIFT_MASK) == 0)) 456 { 457 getAppletContext().showDocument(hrefURL, hrefTarget); 459 } 460 461 showStatus(getAppletInfo() + " -- " + userInstructions); 462 } 463 464 public void mouseReleased(MouseEvent event) { 465 } 466 467 public void mouseEntered(MouseEvent event) { 468 } 469 470 public void mouseExited(MouseEvent event) { 471 } 472 } 473 474 477 class Animation extends Object { 478 static final int STARTUP_ID = 0; 479 static final int BACKGROUND_ID = 1; 480 static final int ANIMATION_ID = 2; 481 static final String imageLabel = "image"; 482 static final String soundLabel = "sound"; 483 484 int globalPause = 1300; List frames = null; int currentFrame; Image startUpImage = null; Image backgroundImage = null; AudioClip soundTrack = null; Color backgroundColor = null; URL backgroundImageURL = null; URL startUpImageURL = null; URL soundTrackURL = null; URL imageSource = null; URL soundSource = null; boolean repeat; Image offScrImage; Graphics offScrGC; MediaTracker tracker; Animator owner; 502 Animation(Animator container) { 503 super(); 504 owner = container; 505 } 506 507 void init() { 508 tracker = new MediaTracker(owner); 509 currentFrame = 0; 510 loadAnimationMedia(); 511 } 512 513 void setGlobalPause(int pause) { 514 globalPause = pause; 515 } 516 517 520 void loadAnimationMedia() { 521 URL badURL; 522 boolean error; 523 try { 524 if (startUpImageURL != null) { 525 owner.tellLoadingMsg(startUpImageURL, imageLabel); 526 startUpImage = fetchImageAndWait(startUpImageURL, STARTUP_ID); 527 if (tracker.isErrorID(STARTUP_ID)) { 528 owner.loadError(startUpImageURL, "start-up image"); 529 } 530 owner.repaint(); 531 } 532 533 if (backgroundImageURL != null) { 534 owner.tellLoadingMsg(backgroundImageURL, imageLabel); 535 backgroundImage = fetchImageAndWait(backgroundImageURL, 536 BACKGROUND_ID); 537 if (tracker.isErrorID(BACKGROUND_ID)) 538 owner.loadError(backgroundImageURL, 539 "background image"); 540 owner.repaint(); 541 } 542 543 Iterator iterator = frames.iterator(); 545 while(iterator.hasNext()) { 546 AnimationFrame frame = (AnimationFrame) iterator.next(); 547 owner.tellLoadingMsg(frame.imageLocation, imageLabel); 548 frame.image = owner.getImage(frame.imageLocation); 549 tracker.addImage(frame.image, ANIMATION_ID); 550 try { 551 tracker.waitForID(ANIMATION_ID); 552 } catch (InterruptedException e) {} 553 } 554 555 if (soundTrackURL != null && soundTrack == null) { 556 owner.tellLoadingMsg(soundTrackURL, imageLabel); 557 soundTrack = owner.getAudioClip(soundTrackURL); 558 if (soundTrack == null) { 559 owner.loadError(soundTrackURL, "soundtrack"); 560 return; 561 } 562 } 563 564 iterator = frames.iterator(); 566 while(iterator.hasNext()) { 567 AnimationFrame frame = (AnimationFrame) iterator.next(); 568 if (frame.soundLocation != null) { 569 owner.tellLoadingMsg(frame.soundLocation, soundLabel); 570 try { 571 frame.sound = owner.getAudioClip(frame.soundLocation); 572 } catch (Exception ex) { 573 owner.loadError(frame.soundLocation, soundLabel); 574 } 575 } 576 } 577 578 owner.clearLoadingMessage(); 579 offScrImage = owner.createImage(owner.appWidth, owner.appHeight); 580 offScrGC = offScrImage.getGraphics(); 581 offScrGC.setColor(Color.lightGray); 582 owner.loaded = true; 583 error = false; 584 } catch (Exception e) { 585 error = true; 586 e.printStackTrace(); 587 } 588 } 589 590 594 Image fetchImageAndWait(URL imageURL, int trackerClass) 595 throws InterruptedException { 596 Image image = owner.getImage(imageURL); 597 tracker.addImage(image, trackerClass); 598 tracker.waitForID(trackerClass); 599 return image; 600 } 601 602 606 void prepareImageRange(int startImage, int endImage, String pattern) 607 throws MalformedURLException { 608 frames = new ArrayList (Math.abs(endImage - startImage) + 1); 609 if (pattern == null) 610 pattern = "T%N.gif"; 611 if (startImage > endImage) { 612 for (int i = startImage; i >= endImage; i--) { 613 AnimationFrame frame = new AnimationFrame(); 614 frames.add(frame); 615 frame.duration = globalPause; 616 frame.imageLocation = new URL (imageSource, 617 doSubst(pattern, i+"")); 618 } 619 } else { 620 for (int i = startImage; i <= endImage; i++) { 621 AnimationFrame frame = new AnimationFrame(); 622 frames.add(frame); 623 frame.duration = globalPause; 624 frame.imageLocation = new URL (imageSource, 625 doSubst(pattern, i+"")); 626 } 627 } 628 } 629 630 636 void parseSounds(String attr) throws MalformedURLException { 637 int frameIndex = 0; 638 int numFrames = frames.size(); 639 for (int i = 0; (i < attr.length()) && (frameIndex < numFrames); ) { 640 int next = attr.indexOf('|', i); 641 if (next == -1) next = attr.length(); 642 String sound = attr.substring(i, next); 643 if (sound.length() != 0) { 644 AnimationFrame frame = (AnimationFrame) frames.get(frameIndex); 645 frame.soundLocation = new URL (soundSource, sound); 646 } 647 i = next + 1; 648 frameIndex++; 649 } 650 } 651 652 656 void parseImages(String attr, String pattern) 657 throws MalformedURLException { 658 frames = new ArrayList (); 659 if (pattern == null) 660 pattern = "T%N.gif"; 661 for (int i = 0; i < attr.length(); ) { 662 int next = attr.indexOf('|', i); 663 if (next == -1) next = attr.length(); 664 String file = attr.substring(i, next); 665 AnimationFrame frame = new AnimationFrame(); 666 frames.add(frame); 667 frame.imageLocation = new URL (imageSource, doSubst(pattern, file)); 668 frame.duration = globalPause; 669 i = next + 1; 670 } 671 } 672 673 682 void parseDurations(String attr) { 683 int imageNum = 0; 684 int numImages = frames.size(); 685 for (int i = 0; (i < attr.length()) && (imageNum < numImages); ) { 686 int next = attr.indexOf('|', i); 687 if (next == -1) next = attr.length(); 688 AnimationFrame aFrame = (AnimationFrame) frames.get(imageNum); 689 if (i != next) { 690 int duration = Integer.parseInt(attr.substring(i, next)); 691 aFrame.duration = duration; 692 } 693 i = next + 1; 694 imageNum++; 695 } 696 } 697 698 701 Point parsePoint(String s) throws ParseException { 702 int atPos = s.indexOf('@'); 703 if (atPos == -1) throw new ParseException("Illegal position: "+s); 704 return new Point(Integer.parseInt(s.substring(0, atPos)), 705 Integer.parseInt(s.substring(atPos + 1))); 706 } 707 708 716 void parsePositions(String param) 717 throws ParseException { 718 int imageNum = 0; 719 int numImages = frames.size(); 720 for (int i = 0; (i < param.length()) && (imageNum < numImages); ) { 721 int next = param.indexOf('|', i); 722 if (next == -1) 723 next = param.length(); 724 if (i != next) { 725 AnimationFrame frame = (AnimationFrame) frames.get(imageNum); 726 frame.position = parsePoint(param.substring(i, next)); 727 } 728 i = next + 1; 729 imageNum++; 730 } 731 } 732 733 744 String doSubst(String inStr, String theInt) { 745 String padStr = "0000000000"; 746 int length = inStr.length(); 747 StringBuffer result = new StringBuffer (length); 748 749 for (int i = 0; i < length;) { 750 char ch = inStr.charAt(i); 751 if (ch == '%') { 752 i++; 753 if (i == length) { 754 result.append(ch); 755 } else { 756 ch = inStr.charAt(i); 757 if (ch == 'N' || ch == 'n') { 758 result.append(theInt); 760 i++; 761 } else { 762 int pad; 763 if ((pad = Character.digit(ch, 10)) != -1) { 764 String numStr = theInt; 766 String scr = padStr+numStr; 767 result.append(scr.substring(scr.length() - pad)); 768 i++; 769 } else { 770 result.append(ch); 771 i++; 772 } 773 } 774 } 775 } else { 776 result.append(ch); 777 i++; 778 } 779 } 780 return result.toString(); 781 } 782 783 void startPlaying() { 784 if (soundTrack != null) { 785 soundTrack.loop(); 786 } 787 } 788 789 void stopPlaying() { 790 if (soundTrack != null) { 791 soundTrack.stop(); 792 } 793 } 794 795 public void paint(Graphics g) { 796 int xPos = 0; 797 int yPos = 0; 798 if ((frames.size() > 0) && tracker.checkID(ANIMATION_ID) && 799 (offScrGC != null)) { 800 AnimationFrame frame = (AnimationFrame) frames.get(currentFrame); 801 Image image = frame.image; 802 if (backgroundImage == null) { 803 offScrGC.clearRect(0, 0, owner.appWidth, owner.appHeight); 804 } 805 else 806 offScrGC.drawImage(backgroundImage, 0, 0, owner); 807 Point pos = null; 808 if (frame.position != null) { 809 xPos = frame.position.x; 810 yPos = frame.position.y; 811 } 812 if (backgroundColor != null) { 813 offScrGC.setColor(backgroundColor); 814 offScrGC.fillRect(0, 0, owner.appWidth, owner.appHeight); 815 offScrGC.drawImage(image, xPos, yPos, backgroundColor, owner); 816 } else { 817 offScrGC.drawImage(image, xPos, yPos, owner); 818 } 819 if (offScrImage != null) 820 g.drawImage(offScrImage, 0, 0, owner); 821 } 822 } 823 } 824 825 829 class AnimationFrame extends Object { 830 static final String imageLabel = "image"; 831 static final String soundLabel = "sound"; 832 833 URL imageLocation = null; URL soundLocation = null; int duration; AudioClip sound; Image image; Point position; 840 } 841 842 845 class ParseException extends Exception { 846 ParseException(String s) { 847 super(s); 848 } 849 } 850 851 854 class DescriptionFrame extends Frame implements ActionListener { 855 static final int rows = 27; 856 static final int cols = 70; 857 TextArea info; 858 Button cancel; 859 860 DescriptionFrame() { 861 super("Animator v1.10"); 862 add("Center", info = new TextArea(rows, cols)); 863 info.setEditable(false); 864 info.setBackground(Color.white); 865 Panel buttons = new Panel(); 866 add("South", buttons); 867 buttons.add(cancel = new Button("Cancel")); 868 cancel.addActionListener(this); 869 pack(); 870 } 871 872 public void show() { 873 info.select(0,0); 874 super.show(); 875 } 876 877 void tell(String s) { 878 info.append(s); 879 } 880 881 public void actionPerformed(ActionEvent e) { 882 setVisible(false); 883 } 884 } 885 886
| Popular Tags
|