home *** CD-ROM | disk | FTP | other *** search
/ Learn Java Now / Learn_Java_Now_Microsoft_1996.iso / JavaNow / Code / Chap15 / Stock / Stock.java < prev    next >
Encoding:
Java Source  |  1996-06-06  |  6.4 KB  |  258 lines

  1. // Stock1 - this applet displays a scrolling graph of
  2. //          data similar to that produced by plotting
  3. //          stock price against time. this version
  4. //          flickers badly when the frame rate is too
  5. //          high.
  6. import java.applet.*;
  7. import java.awt.*;
  8. import java.util.Random;
  9.  
  10. public class Stock extends Applet implements Runnable
  11. {
  12.     Thread     m_Stock = null;
  13.  
  14.     int m_fps = 10;
  15.  
  16.     final String PARAM_fps = "fps";
  17.  
  18.     // use the random object to create stock movements
  19.     private Random  m_r = new Random();
  20.  
  21.     // m_dValue[] - contains the closing price of the stock
  22.     //              for day that is visible. [0] is today
  23.     //              day, [1] yesterday, etc.
  24.     private double[] m_dValue;
  25.     private int m_nSize;  // length of value array
  26.     private int m_nMax;   // maximum value in value array
  27.  
  28.     public Stock()
  29.     {
  30.     }
  31.  
  32.     public void finalize()
  33.     {
  34.     }
  35.  
  36.     public String getAppletInfo()
  37.     {
  38.         return "Name: Stock\r\n" +
  39.                "Author: Stephan R. Davis\r\n" +
  40.                "Created for Learn Java Now (c)";
  41.     }
  42.  
  43.     public String[][] getParameterInfo()
  44.     {
  45.         String[][] info =
  46.         {
  47.             { PARAM_fps, "int", "Frame rate" },
  48.         };
  49.         return info;        
  50.     }
  51.  
  52.     public void init()
  53.     {
  54.         String param;
  55.  
  56.         param = getParameter(PARAM_fps);
  57.         if (param != null)
  58.             m_fps = Integer.parseInt(param);
  59.  
  60.         // resize(600, 240);
  61.  
  62.         // initialize the m_dValue array to the current
  63.         // width of the window
  64.         Dimension dim = size();
  65.         int m_nSize = XToIndex(dim.width);
  66.         m_dValue = new double[m_nSize];
  67.         m_nMax = 100;
  68.     }
  69.  
  70.     public void destroy()
  71.     {
  72.     }
  73.  
  74.     public void paint(Graphics g)
  75.     {
  76.         // paint the frame
  77.         PaintFrame(g);    
  78.  
  79.         // paint the data
  80.         PaintData(g);
  81.     }
  82.  
  83.     private void PaintFrame(Graphics g)
  84.     {
  85.         // get the dimensions of the window
  86.         Dimension d = size();
  87.         int nWidth  = d.width;
  88.         int nHeight = d.height;
  89.  
  90.         // put up axis along the left and bottom
  91.         g.drawString(Integer.toString(m_nMax), 5, 10);
  92.         g.drawString("0", 5, d.height - 10);
  93.         g.drawLine(0, nHeight - 1, nWidth, nHeight - 1);
  94.         g.drawLine(0, nHeight - 1, 0, 0);
  95.         int nMark = 50;
  96.         while (nMark < m_nMax)
  97.         {
  98.             int nL = 3;
  99.             if ((nMark % 100) == 0)
  100.             {
  101.                  nL = 6;
  102.             }
  103.             int nH = ValueToY(nHeight, nMark);
  104.             g.drawLine(0, nH, nL, nH);
  105.             nMark += 50;
  106.         }
  107.     }
  108.  
  109.     synchronized private void PaintData(Graphics g)
  110.     {
  111.         // get the dimensions of the window
  112.         Dimension d = size();
  113.         int nWidth = d.width;
  114.         int nHeight = d.height;
  115.  
  116.         // check to see if the array needs resizing
  117.         ResizeArray(d.width);
  118.  
  119.         // repaint the data
  120.         for (int i = 0; i < m_nSize; i++)
  121.         {
  122.             int x = IndexToX(nWidth, i);
  123.             int y = ValueToY(nHeight, m_dValue[i]);
  124.             g.drawLine(x - 1, y, x + 1, y);
  125.             g.drawLine(x, y - 1, x, y + 1);
  126.         }
  127.     }
  128.  
  129.     public void start()
  130.     {
  131.         if (m_Stock == null)
  132.         { 
  133.             m_Stock = new Thread(this);
  134.             m_Stock.start();
  135.         }
  136.     }
  137.     
  138.     public void stop()
  139.     {
  140.         if (m_Stock != null)
  141.         {
  142.             m_Stock.stop();
  143.             m_Stock = null;
  144.         }
  145.     }
  146.  
  147.     public void run()
  148.     {
  149.         // calculate the proper time to delay
  150.         int nSleepTime = 1000 / m_fps;
  151.  
  152.         // start with the first value stored.
  153.         // if it's zero then this must be
  154.         // the first time into the applet -
  155.         // start with an initial value of 50.
  156.         double dValue = m_dValue[0];
  157.         if (dValue == 0.0)
  158.         {
  159.             dValue = 50.0;
  160.         }
  161.  
  162.         while (true)
  163.         {
  164.             try
  165.             {
  166.                 // create a new stock value
  167.                 // this is the part that's random
  168.                 // (here I assume that movement of plus
  169.                 // or minus two points a day or so is
  170.                 // reasonable - the 0.2 offset gives it
  171.                 // a slight upward drift)
  172.                 dValue += 2 * m_r.nextGaussian() + 0.2;
  173.                 AddValue(dValue);
  174.                 
  175.                 // now repaint the window
  176.                 repaint();
  177.  
  178.                 // repaint at the fps speed
  179.                 Thread.sleep(nSleepTime);
  180.             }
  181.             catch (InterruptedException e)
  182.             {
  183.                 stop();
  184.             }
  185.         }
  186.     }
  187.  
  188.     // ResizeArray - resize the array of stock prices
  189.     //               (if necessary)
  190.     private void ResizeArray(int nWidth)
  191.     {
  192.         // if the window is the same size...
  193.         int nNumPts = XToIndex(nWidth);
  194.         if (nNumPts == m_nSize)
  195.         {
  196.             // ...then ignore it
  197.             return;
  198.         }
  199.  
  200.         // otherwise, we need to resize the array:
  201.         // allocate room
  202.         double[] dNewArray = new double[nNumPts];
  203.  
  204.         // now copy the points from the old, smaller
  205.         // array to the new, larger array
  206.         int nNumToCopy = Math.min(nNumPts, m_nSize);
  207.         for (int i = 0; i < nNumToCopy; i++)
  208.         {
  209.             dNewArray[i] = m_dValue[i];
  210.         }
  211.  
  212.         // finally, make the new array our own
  213.         m_dValue = dNewArray;
  214.         m_nSize = nNumPts;
  215.     }
  216.  
  217.     // AddValue - add a value to the array
  218.     synchronized private void AddValue(double dValue)
  219.     {
  220.         // move everything over one to make
  221.         // room for the new data item
  222.         for (int i = m_nSize - 1; i > 0; i--)
  223.         {
  224.             m_dValue[i] = m_dValue[i - 1];
  225.         }
  226.  
  227.         // add the new data item as the
  228.         // the first entry
  229.         m_dValue[0] = dValue;
  230.  
  231.         // make sure to keep track of the max
  232.         while (dValue >= m_nMax)
  233.         {
  234.             m_nMax += 50;
  235.         }
  236.     }
  237.  
  238.     // XToIndex - convert the display window dimension
  239.     //            to the corresponding array index
  240.     private static final int m_PIXELS_PER_POINT = 3;
  241.     static private int XToIndex(int nWidth)
  242.     {
  243.         return nWidth / m_PIXELS_PER_POINT;
  244.     }
  245.     // IndexToX - convert the array index to the window
  246.     //            x offset
  247.     static private int IndexToX(int nWidth, int nIndex)
  248.     {
  249.         return (nWidth - 1) - (m_PIXELS_PER_POINT * nIndex);
  250.     }
  251.     // ValueToY - convert the stock value into the y
  252.     //            offset in the window to plot the point
  253.     private int ValueToY(int nHeight, double dValue)
  254.     {
  255.         return nHeight - ((int)dValue * nHeight) / m_nMax;
  256.     }
  257. }
  258.