home *** CD-ROM | disk | FTP | other *** search
/ ActiveX Programming Unleashed CD / AXU.iso / source / chap12 / java / spinningredtorus.java < prev    next >
Encoding:
Java Source  |  1996-09-09  |  14.8 KB  |  401 lines

  1. //*****************************************************************
  2. // Applet   : SpinningRedTorus.java
  3. //
  4. // Author   : Rob McGregor
  5. //
  6. // Comments : Adapted from the Visual J++ Applet Wizard default 
  7. //            animation applet
  8. //*****************************************************************
  9.  
  10. import java.applet.*;
  11. import java.awt.*;
  12.  
  13. //=================================================================
  14. // Main Class for applet SpinningRedTorus
  15. //=================================================================
  16.  
  17. public class SpinningRedTorus extends Applet implements Runnable
  18. {
  19.    //--------------------------------------------------------------
  20.    // THREAD SUPPORT:
  21.    //--------------------------------------------------------------
  22.    //   m_SpinningRedTorus Thread object for the applet
  23.    //--------------------------------------------------------------
  24.    Thread    m_SpinningRedTorus = null;
  25.  
  26.    //--------------------------------------------------------------
  27.    // ANIMATION SUPPORT:
  28.    //--------------------------------------------------------------
  29.    // m_Graphics     stores the applet's Graphics context
  30.    // m_Images[]     the array of Image objects for the animation
  31.    // m_nCurrImage   the index of the next image to be displayed
  32.    // m_ImgWidth     width of each image
  33.    // m_ImgHeight    height of each image
  34.    // m_fAllLoaded   indicates whether all images have been loaded
  35.    // IMAGE_LAST     number of images used in the animation
  36.    //--------------------------------------------------------------
  37.    private Graphics  m_Graphics;
  38.    private Image     m_Images[];
  39.    private int       m_nCurrImage;
  40.    private int       m_nImgWidth   = 0;
  41.    private int       m_nImgHeight  = 0;
  42.    private boolean   m_fAllLoaded  = false;
  43.  
  44.    // Constants
  45.    private final int NUM_IMAGES = 12;
  46.    private final int FORWARD    = 1;
  47.    private final int BACKWARD   = 0;
  48.  
  49.    //--------------------------------------------------------------
  50.    // PARAMETER SUPPORT:
  51.    //--------------------------------------------------------------
  52.    // Parameters allow an HTML author to pass information to 
  53.    // the applet; the HTML author specifies them using the <PARAM> 
  54.    // tag within the <APPLET> tag. The following variables are 
  55.    // used to store the values of the parameters.
  56.    //--------------------------------------------------------------
  57.  
  58.    // Members for applet parameters
  59.    private int m_Interval  = 100;
  60.    private int m_Direction = 0;
  61.  
  62.    // Parameter names. To change a name of a parameter, you need 
  63.    // only make a single change. Simply modify the value of the 
  64.    // parameter string below.
  65.    //--------------------------------------------------------------
  66.    private final String PARAM_Interval  = "Interval";
  67.    private final String PARAM_Direction = "Direction";
  68.  
  69.    //==============================================================
  70.    // SpinningRedTorus Class Constructor
  71.    //==============================================================
  72.  
  73.    public SpinningRedTorus()
  74.    {
  75.       // Add constructor code here
  76.    }
  77.  
  78.    //==============================================================
  79.    // public String getAppletInfo()
  80.    //--------------------------------------------------------------
  81.    // Returns a string describing the applet's author, copyright 
  82.    // date, or miscellaneous information
  83.    //==============================================================
  84.  
  85.    public String getAppletInfo()
  86.    {
  87.       return "Name: SpinningRedTorus\r\n" +
  88.              "Author: Rob McGregor\r\n" +
  89.              "Created with Microsoft Visual J++ Version 1.0";
  90.    }
  91.  
  92.    //==============================================================
  93.    // public String[][] getParameterInfo()
  94.    //--------------------------------------------------------------
  95.    // The getParameterInfo() method returns an array of strings 
  96.    // describing the parameters understood by this applet.
  97.    //
  98.    // SpinningRedTorus Parameter Information:
  99.    //  { "Name", "Type", "Description" },
  100.    //==============================================================
  101.  
  102.    public String[][] getParameterInfo()
  103.    {
  104.       String[][] info =
  105.       {
  106.          { PARAM_Interval, "int", "Interval between frames" },
  107.          { PARAM_Direction, "int", "Forward or backward (1 or 0)" },
  108.       };
  109.       return info;      
  110.    }
  111.  
  112.    //==============================================================
  113.    // public void init()
  114.    //--------------------------------------------------------------
  115.    // Called by the AWT when an applet is first loaded or reloaded
  116.    // Override this method to perform whatever initialization your 
  117.    // applet needs, such as initializing data structures, loading 
  118.    // images or fonts, creating frame windows, setting the layout 
  119.    // manager, or adding UI components.
  120.    //==============================================================
  121.  
  122.    public void init()
  123.    {
  124.       // The following code retrieves the value of each parameter
  125.       // specified with the <PARAM> tag and stores it in a member
  126.       // variable.
  127.       //-----------------------------------------------------------
  128.       String param;
  129.  
  130.       // Interval: Interval between frames
  131.       //-----------------------------------------------------------
  132.       param = getParameter(PARAM_Interval);
  133.       if (param != null)
  134.          m_Interval = Integer.parseInt(param);
  135.  
  136.       // Direction: Forward or backward (1 or 0)
  137.       //-----------------------------------------------------------
  138.       param = getParameter(PARAM_Direction);
  139.       if (param != null)
  140.          m_Direction = Integer.parseInt(param);
  141.  
  142.       resize(160, 120);
  143.    }
  144.  
  145.    //==============================================================
  146.    // public void destroy()
  147.    //--------------------------------------------------------------
  148.    // Called when when the applet is terminating, place additional 
  149.    // applet clean up code here.  
  150.    //==============================================================
  151.  
  152.    public void destroy()
  153.    {
  154.       // Place applet cleanup code here
  155.    }
  156.  
  157.    //==============================================================
  158.    // public boolean imageUpdate()
  159.    //--------------------------------------------------------------
  160.    // The imageUpdate() method is called repeatedly by the AWT 
  161.    // while images are being constructed.  The flags parameter 
  162.    // provides information about the status of images under 
  163.    // construction. This method checks whether the ALLBITS flag is 
  164.    // set, which means that an image is completely loaded. When all
  165.    // the images are completely loaded, this method sets the 
  166.    // m_fAllLoaded variable to true so that animation can begin.
  167.    //==============================================================
  168.  
  169.    public boolean imageUpdate(Image img, int flags, int x, int y, 
  170.       int w, int h)
  171.    {
  172.       // Nothing to do if images are all loaded
  173.       //-----------------------------------------------------------
  174.       if (m_fAllLoaded)
  175.          return false;
  176.  
  177.       // Want all bits to be available before painting
  178.       //-----------------------------------------------------------
  179.       if ((flags & ALLBITS) == 0)
  180.          return true;
  181.  
  182.       // All bits are available, so increment loaded count of fully
  183.       // loaded images, starting animation if all images are loaded
  184.       //-----------------------------------------------------------
  185.       if (++m_nCurrImage == NUM_IMAGES)
  186.       {
  187.          m_nCurrImage = 
  188.             (FORWARD == m_Direction) ? 0 : NUM_IMAGES - 1;
  189.  
  190.          m_fAllLoaded = true;
  191.       }            
  192.  
  193.       return false;
  194.    }
  195.  
  196.    //==============================================================
  197.    // private void displayImage()
  198.    //--------------------------------------------------------------
  199.    // Draws the next image (if all images are currently loaded)
  200.    //==============================================================
  201.  
  202.    private void displayImage(Graphics g)
  203.    {
  204.       if (!m_fAllLoaded)
  205.          return;
  206.  
  207.       // Draw Image in center of applet
  208.       //-----------------------------------------------------------
  209.       g.drawImage(m_Images[m_nCurrImage], 
  210.          (size().width - m_nImgWidth) / 2,
  211.          (size().height - m_nImgHeight) / 2, null);
  212.    }
  213.  
  214.    //==============================================================
  215.    // public void paint(Graphics g)
  216.    //--------------------------------------------------------------
  217.    // SpinningRedTorus Paint Handler
  218.    //==============================================================
  219.  
  220.    public void paint(Graphics g)
  221.    {
  222.       // The following code displays a status message until all the
  223.       // images are loaded. Then it calls displayImage to display 
  224.       // the current image.
  225.       //-----------------------------------------------------------
  226.       if (m_fAllLoaded)
  227.       {
  228.          Rectangle r = g.getClipRect();
  229.          
  230.          g.clearRect(r.x, r.y, r.width, r.height);
  231.          displayImage(g);
  232.       }
  233.       else
  234.          g.drawString("Loading ray traced images...", 10, 20);
  235.    }
  236.  
  237.    //==============================================================
  238.    // public void start()
  239.    //--------------------------------------------------------------
  240.    // Called when the page containing the applet first appears on 
  241.    // the screen to start execution of the applet's thread.
  242.    //==============================================================
  243.  
  244.    public void start()
  245.    {
  246.       if (m_SpinningRedTorus == null)
  247.       {
  248.          m_SpinningRedTorus = new Thread(this);
  249.          m_SpinningRedTorus.start();
  250.       }
  251.    }
  252.    
  253.    //==============================================================
  254.    // public void stop()
  255.    //--------------------------------------------------------------
  256.    // Called when the page containing the applet is no longer on 
  257.    // the screen. This method stops execution of the applet's 
  258.    // thread.
  259.    //==============================================================
  260.  
  261.    public void stop()
  262.    {
  263.       if (m_SpinningRedTorus != null)
  264.       {
  265.          m_SpinningRedTorus.stop();
  266.          m_SpinningRedTorus = null;
  267.       }
  268.    }
  269.  
  270.    //==============================================================
  271.    // public void run()
  272.    //--------------------------------------------------------------
  273.    // Called when the applet's thread is started. If your applet 
  274.    // performs any ongoing activities without waiting for user 
  275.    // input, the code for implementing that behavior typically goes
  276.    // here. For example, for an applet that performs animation, 
  277.    // the run() method controls the display of images.
  278.    //==============================================================
  279.    
  280.    public void run()
  281.    {
  282.       repaint();
  283.  
  284.       m_Graphics   = getGraphics();
  285.       m_nCurrImage = 0;
  286.       m_Images     = new Image[NUM_IMAGES];
  287.  
  288.       // Load in all the images
  289.       //-----------------------------------------------------------
  290.       String strImage;
  291.  
  292.       // For each image in the animation, this method first
  293.       // constructs a string containing the path to the image file;
  294.       // then it begins loading the image into the m_Images array.
  295.       // Note that the call to getImage() will return before the 
  296.       // image is completely loaded.
  297.       //-----------------------------------------------------------
  298.       for (int i = 1; i <= NUM_IMAGES; i++)
  299.       {
  300.          // Build path to next image
  301.          //--------------------------------------------------------
  302.          strImage = "./images/img00" + ((i < 10) ? "0" : "") 
  303.             + i + ".gif";
  304.          m_Images[i-1] = getImage(getDocumentBase(), strImage);
  305.  
  306.          // Get width and height of one image.
  307.          // Assuming all images are same width and height
  308.          //--------------------------------------------------------
  309.          if (m_nImgWidth == 0)
  310.          {
  311.             try
  312.             {
  313.                // The getWidth() and getHeight() methods of the 
  314.                // Image class return -1 if the dimensions are not 
  315.                // yet known. The following code keeps calling 
  316.                // getWidth() and getHeight() until they return 
  317.                // actual values.
  318.                //
  319.                // NOTE:
  320.                // This is only executed once in this loop, since 
  321.                // we are assuming all images are the same width 
  322.                // and height.  However, since we do not want to 
  323.                // duplicate the above image load code, the code 
  324.                // resides in the loop.
  325.                //--------------------------------------------------
  326.                while ((m_nImgWidth = 
  327.                   m_Images[i-1].getWidth(null)) < 0)
  328.                   Thread.sleep(1);
  329.  
  330.                while ((m_nImgHeight = 
  331.                   m_Images[i-1].getHeight(null)) < 0)
  332.                   Thread.sleep(1);                  
  333.             }
  334.             catch (InterruptedException e)
  335.             {
  336.                // Place exception-handling code here in case an
  337.                // InterruptedException is thrown by Thread.sleep(),
  338.                // meaning that another thread has interrupted this
  339.                // one
  340.             }
  341.          }
  342.  
  343.          // Force image to fully load
  344.          //--------------------------------------------------------
  345.          m_Graphics.drawImage(m_Images[i-1], -1000, -1000, this);
  346.       }
  347.  
  348.       // Wait until all images are fully loaded
  349.       //-----------------------------------------------------------
  350.       while (!m_fAllLoaded)
  351.       {
  352.          try
  353.          {
  354.             Thread.sleep(10);
  355.          }
  356.          catch (InterruptedException e)
  357.          {
  358.             // Place exception-handling code here in case an
  359.             // InterruptedException is thrown by Thread.sleep(),
  360.             // meaning that another thread has interrupted this
  361.             // one
  362.          }
  363.       }
  364.       
  365.       repaint();
  366.  
  367.       while (true)
  368.       {
  369.          try
  370.          {
  371.             // Draw next image in animation
  372.             //-----------------------------------------------------
  373.             displayImage(m_Graphics);
  374.             if (m_Direction == FORWARD)   // 1
  375.             {
  376.                m_nCurrImage++;
  377.                if (m_nCurrImage == NUM_IMAGES)
  378.                   m_nCurrImage = 0;
  379.             }
  380.             if (m_Direction == BACKWARD)  // 0
  381.             {
  382.                m_nCurrImage--;
  383.                if (m_nCurrImage <= 0)
  384.                   m_nCurrImage = NUM_IMAGES - 1;
  385.             }
  386.  
  387.             // Set the animation to desired speed
  388.             Thread.sleep(m_Interval);
  389.          }
  390.          catch (InterruptedException e)
  391.          {
  392.             // Place exception-handling code here in case an
  393.             // InterruptedException is thrown by Thread.sleep(),
  394.             // meaning that another thread has interrupted this
  395.             // one
  396.             stop();
  397.          }
  398.       }
  399.    }
  400. }
  401.