home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / IFC_112 / netscape / application / ImageSequence.java < prev    next >
Encoding:
Text File  |  1999-05-28  |  13.5 KB  |  433 lines  |  [TEXT/CWIE]

  1. // ImageSequence.java
  2. // By Ned Etcode
  3. // Copyright 1995, 1996, 1997 Netscape Communications Corp.  All rights reserved.
  4.  
  5. package netscape.application;
  6.  
  7. import netscape.util.*;
  8.  
  9.  
  10. /** DrawingSequence subclass that animates a collection of Images (Bitmaps or
  11.   * other).  You can add one or more Images to an ImageSequence by hand, or
  12.   * if you're working with a number of Bitmaps that share the same name except
  13.   * for a number suffix (i.e. Ball0, Ball1, Ball2, etc.), you can provide
  14.   * the ImageSequence with the first Bitmap name and a count, and the
  15.   * ImageSequence will load each Bitmap itself.  ImageSequences can also
  16.   * produce an animation from a single Image that contains a number of frames
  17.   * (oriented either vertically or horizontally).  Given an "Image strip" Image
  18.   * and a frame width or height, the ImageSequence will treat and display
  19.   * portions of the single Image as individual frames.
  20.   */
  21.  
  22. public class ImageSequence extends DrawingSequence {
  23.     Vector      imageVector;
  24.     Image       imageStrip;
  25.     int         frameWidth, frameHeight;
  26.  
  27.     final static String         VECTOR_KEY = "imageVector",
  28.                                 IMAGESTRIP_KEY = "imageStrip",
  29.                                 FRAMEWIDTH_KEY = "frameWidth",
  30.                                 FRAMEHEIGHT_KEY = "frameHeight";
  31.  
  32.  
  33.  
  34.     /* constructors */
  35.  
  36.     /** Constructs an ImageSequence without an owner.
  37.       */
  38.     public ImageSequence() {
  39.         super();
  40.     }
  41.  
  42.     /** Constructs an ImageSequence with owner <B>owner</B>, a frame
  43.       * rate of 1 millisecond, current frame number of 0, and a direction of
  44.       * FORWARD.
  45.       */
  46.     public ImageSequence(DrawingSequenceOwner owner) {
  47.         super(owner);
  48.     }
  49.  
  50.     /** Returns the ImageSequence's collection of Images. */
  51.     public Vector images() {
  52.         return imageVector;
  53.     }
  54.  
  55.     /** Adds <b>anImage</b> to the ImageSequence's collection of Images. */
  56.     public void addImage(Image anImage) {
  57.         if (imageVector == null) {
  58.             imageVector = new Vector();
  59.         }
  60.  
  61.         imageVector.addElement(anImage);
  62.         frameCount = imageVector.count();
  63.     }
  64.  
  65.     /** Adds a sequence of Bitmaps with the same name but different number
  66.       * suffixes, such as Ball0, Ball1, Ball2, and so on.
  67.       * <b>firstImageName</b> should be the full name of the first Bitmap
  68.       * (Ball0, in this case), and <b>count</b> should be the total number of
  69.       * images to add, including the first one.  If the Images are named
  70.       * "Ball0," "Ball1," "Ball2," and "Ball3," <b>count</b> should be 4.
  71.       * Calls <b>Bitmap.bitmapNamed()</b> to locate the named Bitmaps.
  72.       */
  73.     public void addImagesFromName(String firstImageName, int count) {
  74.         Application     application;
  75.         String          namePrefix, fileType;
  76.         int             periodIndex, i, nextDigitIndex, startingNumber,
  77.                         columnOffset;
  78.  
  79.         if (firstImageName == null || count < 0) {
  80.             return;
  81.         }
  82.  
  83.         application = Application.application();
  84.  
  85.         periodIndex = firstImageName.lastIndexOf('.');
  86.         if (periodIndex == -1) {
  87.             addImage(Bitmap.bitmapNamed(firstImageName));
  88.             return;
  89.         }
  90.         fileType = firstImageName.substring(periodIndex);
  91.  
  92.         nextDigitIndex = periodIndex - 1;
  93.         startingNumber = 0;
  94.         columnOffset = 1;
  95.         while (nextDigitIndex > 0 &&
  96.                Character.isDigit(firstImageName.charAt(nextDigitIndex))) {
  97.             startingNumber += columnOffset *
  98.                         Character.digit(firstImageName.charAt(nextDigitIndex),
  99.                                         10);
  100.  
  101.             columnOffset *= 10;
  102.             nextDigitIndex--;
  103.         }
  104.  
  105.         namePrefix = firstImageName.substring(0, nextDigitIndex + 1);
  106.  
  107.         if (imageVector == null) {
  108.             imageVector = new Vector();
  109.         }
  110.  
  111.         count += startingNumber;
  112.         for (i = startingNumber; i < count; i++) {
  113.             imageVector.addElement(Bitmap.bitmapNamed(
  114.                                                 namePrefix + i + fileType));
  115.         }
  116.  
  117.         frameCount = imageVector.count();
  118.     }
  119.  
  120.     /** Removes <b>anImage</b> from the ImageSequence's collection of
  121.       * Images.
  122.       */
  123.     public void removeImage(Image anImage) {
  124.         if (imageVector != null) {
  125.             imageVector.removeElement(anImage);
  126.             frameCount = imageVector.count();
  127.         }
  128.     }
  129.  
  130.     /** Empties the ImageSequence of Images and clears its Image strip.
  131.       */
  132.     public void removeAllImages() {
  133.         if (imageVector != null) {
  134.             imageVector.removeAllElements();
  135.         }
  136.         imageStrip = null;
  137.         currentFrameNumber = frameCount = 0;
  138.     }
  139.  
  140.     /** Sets the Image from which the ImageSequence should extract individual
  141.       * frames.  You set the strip's orientation and frame size through the
  142.       * <b>setFrameWidth()</b> or <b>setFrameHeight()</b> methods.
  143.       * @see #setFrameWidth
  144.       * @see #setFrameHeight
  145.       */
  146.     public void setImageStrip(Image anImage) {
  147.         imageStrip = anImage;
  148.         currentFrameNumber = frameCount = 0;
  149.     }
  150.  
  151.     /** Returns the ImageSequence's Image strip.
  152.       * @see #setImageStrip
  153.       */
  154.     public Image imageStrip() {
  155.         return imageStrip;
  156.     }
  157.  
  158.     /** Configures the ImageSequence to extract frames horizontally, assuming a
  159.       * frame width of <b>pixels</b>.
  160.       * @see #setImageStrip
  161.       */
  162.     public void setFrameWidth(int pixels) {
  163.         if (pixels < 0) {
  164.             pixels = 0;
  165.         }
  166.  
  167.         frameWidth = pixels;
  168.         if (frameWidth > 0 && imageStrip != null) {
  169.             frameCount = imageStrip.width() / frameWidth;
  170.         } else {
  171.             currentFrameNumber = frameCount = 0;
  172.         }
  173.     }
  174.  
  175.     /** Returns the ImageSequence's frame width.
  176.       * @see #setFrameWidth
  177.       */
  178.     public int frameWidth() {
  179.         return frameWidth;
  180.     }
  181.  
  182.     /** Configures the ImageSequence to extract frames vertically, assuming a
  183.       * frame height of <b>pixels</b>.
  184.       * @see #setImageStrip
  185.       */
  186.     public void setFrameHeight(int pixels) {
  187.         if (pixels < 0) {
  188.             pixels = 0;
  189.         }
  190.  
  191.         frameHeight = pixels;
  192.         if (frameHeight > 0 && imageStrip != null) {
  193.             frameCount = imageStrip.height() / frameHeight;
  194.         } else {
  195.             currentFrameNumber = frameCount = 0;
  196.         }
  197.     }
  198.  
  199.     /** Returns the ImageSequence's frame height.
  200.       * @see #setFrameHeight
  201.       */
  202.     public int frameHeight() {
  203.         return frameHeight;
  204.     }
  205.  
  206.     /** Returns the number of Images (or frames, in the case of an Image
  207.       * strip) that the ImageSequence will display.
  208.       */
  209.     public int imageCount() {
  210.         return frameCount();
  211.     }
  212.  
  213.     /** Sets the ImageSequence to display Image number <b>imageNumber</b>.
  214.       */
  215.     public void setCurrentImageNumber(int imageNumber) {
  216.         if (imageNumber < 0) {
  217.             imageNumber = 0;
  218.         } else if (imageNumber >= frameCount) {
  219.             imageNumber = frameCount - 1;
  220.         }
  221.  
  222.         currentFrameNumber = imageNumber;
  223.     }
  224.  
  225.     /** Returns the current Image being displayed by the ImageSequence, or
  226.       * its entire Image strip if configured to use one.
  227.       */
  228.     public Image currentImage() {
  229.         if (imageVector != null) {
  230.             return (Image)imageVector.elementAt(currentFrameNumber);
  231.         }
  232.  
  233.         return imageStrip;
  234.     }
  235.  
  236.     /** Returns the unioned Size of the ImageSequence's Images (the minimum
  237.       * area required to fully display each Image).
  238.       */
  239.     public Size maxSize() {
  240.         Image        nextImage;
  241.         int          i, maxWidth, maxHeight;
  242.  
  243.         if (imageStrip != null) {
  244.             if (frameWidth > 0) {
  245.                 return new Size(frameWidth, imageStrip.height());
  246.             } else if (frameHeight > 0) {
  247.                 return new Size(imageStrip.width(), frameHeight);
  248.             }
  249.         } else if (imageVector != null && !imageVector.isEmpty()) {
  250.             maxWidth = maxHeight = 0;
  251.             i = imageVector.count();
  252.             while (i-- > 0) {
  253.                 nextImage = (Image)imageVector.elementAt(i);
  254.                 if (nextImage.width() > maxWidth) {
  255.                     maxWidth = nextImage.width();
  256.                 }
  257.                 if (nextImage.height() > maxHeight) {
  258.                     maxHeight = nextImage.height();
  259.                 }
  260.             }
  261.  
  262.             return new Size(maxWidth, maxHeight);
  263.         }
  264.  
  265.         return new Size(0, 0);
  266.     }
  267.  
  268.     /** Returns the width of the ImageSequence's tallest Image.
  269.       */
  270.     public int width() {
  271.         Image        nextImage;
  272.         int          i, maxWidth = 0;
  273.  
  274.         if (imageStrip != null) {
  275.             if (frameWidth > 0) {
  276.                 return frameWidth;
  277.             } else {
  278.                 return imageStrip.width();
  279.             }
  280.         }
  281.  
  282.         if (imageVector == null) {
  283.             return 0;
  284.         }
  285.  
  286.         i = imageVector.count();
  287.         while (i-- > 0) {
  288.             nextImage = (Image)imageVector.elementAt(i);
  289.             if (nextImage.width() > maxWidth) {
  290.                 maxWidth = nextImage.width();
  291.             }
  292.         }
  293.  
  294.         return maxWidth;
  295.     }
  296.  
  297.     /** Returns the height of the ImageSequence's tallest Image.
  298.       */
  299.     public int height() {
  300.         Image        nextImage;
  301.         int             i, maxHeight = 0;
  302.  
  303.         if (imageStrip != null) {
  304.             if (frameHeight > 0) {
  305.                 return frameHeight;
  306.             } else {
  307.                 return imageStrip.height();
  308.             }
  309.         }
  310.  
  311.         if (imageVector == null) {
  312.             return 0;
  313.         }
  314.  
  315.         i = imageVector.count();
  316.         while (i-- > 0) {
  317.             nextImage = (Image)imageVector.elementAt(i);
  318.             if (nextImage.height() > maxHeight) {
  319.                 maxHeight = nextImage.height();
  320.             }
  321.         }
  322.  
  323.         return maxHeight;
  324.     }
  325.  
  326.     /** Draws the ImageSequence's current Image at (<b>x</b>, <b>y</b>).
  327.       */
  328.     public void drawAt(Graphics g, int x, int y) {
  329.         Image        nextImage;
  330.         Rect         tmpRect;
  331.  
  332.         if (imageVector != null) {
  333.             nextImage = (Image)imageVector.elementAt(currentFrameNumber);
  334.             if (nextImage != null) {
  335.                 // This might not work the way you want if the images have
  336.                 // different sizes.  ALERT!
  337.                 nextImage.drawAt(g, x, y);
  338.             }
  339.         } else if (frameWidth > 0) {
  340.             tmpRect = Rect.newRect(x, y, frameWidth, imageStrip.height());
  341.             g.pushState();
  342.             g.setClipRect(tmpRect);
  343.             imageStrip.drawAt(g, x - frameWidth * currentFrameNumber, y);
  344.             g.popState();
  345.             Rect.returnRect(tmpRect);
  346.         } else if (frameHeight > 0) {
  347.             tmpRect = Rect.newRect(x, y, imageStrip.width(), frameHeight);
  348.             g.pushState();
  349.             g.setClipRect(tmpRect);
  350.             imageStrip.drawAt(g, x, y - frameHeight * currentFrameNumber);
  351.             g.popState();
  352.             Rect.returnRect(tmpRect);
  353.         }
  354.     }
  355.  
  356.     /** Draws the ImageSequence's current Image, scaled to fit the supplied
  357.       * rectangle.
  358.       */
  359.     public void drawScaled(Graphics g, int x, int y, int width, int height) {
  360.         Image        nextImage;
  361.         Rect         tmpRect;
  362.  
  363.         // This doesn't do scaling as you might want.  ALERT!
  364.  
  365.         if (imageVector != null) {
  366.             nextImage = (Image)imageVector.elementAt(currentFrameNumber);
  367.             if (nextImage != null) {
  368.                 nextImage.drawCentered(g, x, y, width, height);
  369.             }
  370.         } else if (frameWidth > 0) {
  371.             x += (width - frameWidth) / 2;
  372.             y += (height - imageStrip.height()) / 2;
  373.             tmpRect = Rect.newRect(x, y, frameWidth, imageStrip.height());
  374.             g.pushState();
  375.             g.setClipRect(tmpRect);
  376.             imageStrip.drawAt(g, x - frameWidth * currentFrameNumber, y);
  377.             g.popState();
  378.             Rect.returnRect(tmpRect);
  379.         } else if (frameHeight > 0) {
  380.             x += (width - imageStrip.width()) / 2;
  381.             y += (height - frameHeight) / 2;
  382.             tmpRect = Rect.newRect(x, y, imageStrip.width(), frameHeight);
  383.             g.pushState();
  384.             g.setClipRect(tmpRect);
  385.             imageStrip.drawAt(g, x, y - frameHeight * currentFrameNumber);
  386.             g.popState();
  387.             Rect.returnRect(tmpRect);
  388.         }
  389.     }
  390.  
  391. /* archiving */
  392.  
  393.  
  394.     /** Describes the ImageSequence class' coding information.
  395.       * @see Codable#describeClassInfo
  396.       */
  397.     public void describeClassInfo(ClassInfo info) {
  398.         super.describeClassInfo(info);
  399.  
  400.         info.addClass("netscape.application.ImageSequence", 1);
  401.         info.addField(VECTOR_KEY, OBJECT_TYPE);
  402.         info.addField(IMAGESTRIP_KEY, OBJECT_TYPE);
  403.         info.addField(FRAMEWIDTH_KEY, INT_TYPE);
  404.         info.addField(FRAMEHEIGHT_KEY, INT_TYPE);
  405.     }
  406.  
  407.     /** Encodes the ImageSequence.
  408.       * @see Codable#encode
  409.       */
  410.     public void encode(Encoder encoder) throws CodingException {
  411.         super.encode(encoder);
  412.  
  413.         encoder.encodeObject(VECTOR_KEY, imageVector);
  414.         encoder.encodeObject(IMAGESTRIP_KEY, imageStrip);
  415.  
  416.         encoder.encodeInt(FRAMEWIDTH_KEY, frameWidth);
  417.         encoder.encodeInt(FRAMEHEIGHT_KEY, frameHeight);
  418.     }
  419.  
  420.     /** Decodes the ImageSequence.
  421.       * @see Codable#decode
  422.       */
  423.     public void decode(Decoder decoder) throws CodingException {
  424.         super.decode(decoder);
  425.  
  426.         imageVector = (Vector)decoder.decodeObject(VECTOR_KEY);
  427.         imageStrip = (Image)decoder.decodeObject(IMAGESTRIP_KEY);
  428.  
  429.         frameWidth = decoder.decodeInt(FRAMEWIDTH_KEY);
  430.         frameHeight = decoder.decodeInt(FRAMEHEIGHT_KEY);
  431.     }
  432. }
  433.