home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / Java++ / VJ / SAMPLES / JAVANOW / CHAP15 / STOCK2 / STOCK.JAVA < prev    next >
Encoding:
Java Source  |  1996-06-18  |  8.6 KB  |  330 lines

  1. // Stock2 - this applet is an "improved" version of the
  2. //          Stock1 applet. This version avoids applet
  3. //          flicker by carefully removing each symbol
  4. //          before putting up the new position. However,
  5. //          this version is slow and difficult to write.
  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.     // m_nOffset - number of values to move the display
  29.     //             during a pan
  30.     private int m_nOffset = 0;
  31.  
  32.     // m_bRepaintAll - setting this flag to true forces
  33.     //                 update to perform a full repaint
  34.     //                 of the applet's window
  35.     private boolean m_bRepaintAll = true;
  36.  
  37.     // m_nWinWidth - the width of the window
  38.     private Dimension m_dimWin = new Dimension(0, 0);
  39.  
  40.     public Stock()
  41.     {
  42.     }
  43.  
  44.     public void finalize()
  45.     {
  46.     }
  47.  
  48.     public String getAppletInfo()
  49.     {
  50.         return "Name: Stock\r\n" +
  51.                "Author: Stephan R. Davis\r\n" +
  52.                "Created for Learn Java Now (c)";
  53.     }
  54.  
  55.     public String[][] getParameterInfo()
  56.     {
  57.         String[][] info =
  58.         {
  59.             { PARAM_fps, "int", "Frame rate" },
  60.         };
  61.         return info;        
  62.     }
  63.  
  64.     public void init()
  65.     {
  66.         String param;
  67.  
  68.         param = getParameter(PARAM_fps);
  69.         if (param != null)
  70.             m_fps = Integer.parseInt(param);
  71.  
  72.         // resize(600, 240);
  73.  
  74.         // initialize the m_dValue array to the current
  75.         // width of the window
  76.         Dimension dim = size();
  77.         int m_nSize = XToIndex(dim.width);
  78.         m_dValue = new double[m_nSize];
  79.         m_nMax = 100;
  80.     }
  81.  
  82.     public void destroy()
  83.     {
  84.     }
  85.  
  86.     public void paint(Graphics g)
  87.     {
  88.         // before we repaint, make sure the whole
  89.         // screen is cleared
  90.         Dimension dim = size();
  91.         g.clearRect(0, 0, dim.width, dim.height);
  92.  
  93.         // paint the frame
  94.         PaintFrame(g);    
  95.  
  96.         // paint the data
  97.         PaintData(g);
  98.  
  99.         // no need to repaint the world again
  100.         m_bRepaintAll = false;
  101.     }
  102.  
  103.     public void update(Graphics g)
  104.     {
  105.         // make sure that the window registers exactly
  106.         Dimension dim = size();
  107.         if (dim.width != m_dimWin.width ||
  108.             dim.height!= m_dimWin.height)
  109.         {
  110.             // window has changed size - repaint everything
  111.             m_bRepaintAll = true;
  112.             m_dimWin = new Dimension(dim.width, dim.height);
  113.         }
  114.  
  115.         // if we need to repaint everything...
  116.         if (m_bRepaintAll)
  117.         {
  118.             // ...then repaint the world...
  119.             paint(g);
  120.         }
  121.         else
  122.         {
  123.             // ...otherwise, just repaint the data
  124.             PaintData(g);
  125.         }
  126.     }
  127.  
  128.     private void PaintFrame(Graphics g)
  129.     {
  130.         // get the dimensions of the window
  131.         Dimension d = size();
  132.         int nWidth  = d.width;
  133.         int nHeight = d.height;
  134.  
  135.         // check to see if the array needs resizing
  136.         ResizeArray(nWidth);
  137.  
  138.         // put up axis along the left and bottom
  139.         g.drawString(Integer.toString(m_nMax), 5, 10);
  140.         g.drawString("0", 5, d.height - 10);
  141.         g.drawLine(0, nHeight - 1, nWidth, nHeight - 1);
  142.         g.drawLine(0, nHeight - 1, 0, 0);
  143.         int nMark = 50;
  144.         while (nMark < m_nMax)
  145.         {
  146.             int nL = 3;
  147.             if ((nMark % 100) == 0)
  148.             {
  149.                  nL = 6;
  150.             }
  151.             int nH = ValueToY(nHeight, nMark);
  152.             g.drawLine(0, nH, nL, nH);
  153.             nMark += 50;
  154.         }
  155.     }
  156.  
  157.     synchronized private void PaintData(Graphics g)
  158.     {
  159.         // get the dimensions of the window
  160.         Dimension d = size();
  161.         int nWidth = d.width;
  162.         int nHeight = d.height;
  163.  
  164.         // if m_nOffset is zero, there's nothing to do
  165.         if (m_nOffset == 0)
  166.         {
  167.             return;
  168.         }
  169.  
  170.         // repaint the data
  171.         Color bg = getBackground();
  172.         Color fg = getForeground();
  173.         int nMax = m_nSize - m_nOffset - 1;
  174.         for (int i = 0; i < nMax; i++)
  175.         {
  176.             int x = IndexToX(nWidth, i);
  177.  
  178.             // remove the old mark in this column
  179.             int y;
  180.             y = ValueToY(nHeight, m_dValue[i + m_nOffset]);
  181.             g.setColor(bg);
  182.             g.drawLine(x - 1, y, x + 1, y);
  183.             g.drawLine(x, y - 1, x, y + 1);
  184.  
  185.             // now draw the new mark in this column
  186.             y = ValueToY(nHeight, m_dValue[i]);
  187.             g.setColor(fg);
  188.             g.drawLine(x - 1, y, x + 1, y);
  189.             g.drawLine(x, y - 1, x, y + 1);
  190.         }
  191.  
  192.         // now that we've repainted, note that by setting
  193.         // the offset back to zero
  194.         m_nOffset = 0;
  195.     }
  196.  
  197.     public void start()
  198.     {
  199.         if (m_Stock == null)
  200.         { 
  201.             m_Stock = new Thread(this);
  202.             m_Stock.start();
  203.         }
  204.     }
  205.     
  206.     public void stop()
  207.     {
  208.         if (m_Stock != null)
  209.         {
  210.             m_Stock.stop();
  211.             m_Stock = null;
  212.         }
  213.     }
  214.  
  215.     public void run()
  216.     {
  217.         // calculate the proper time to delay
  218.         int nSleepTime = 1000 / m_fps;
  219.  
  220.         // start with the first value stored.
  221.         // if it's zero then this must be
  222.         // the first time into the applet -
  223.         // start with an initial value of 50.
  224.         double dValue = m_dValue[0];
  225.         if (dValue == 0.0)
  226.         {
  227.             dValue = 50.0;
  228.         }
  229.  
  230.         while (true)
  231.         {
  232.             try
  233.             {
  234.                 // create a new stock value
  235.                 // this is the part that's random
  236.                 // (here I assume that movement of plus
  237.                 // or minus two points a day or so is
  238.                 // reasonable - the 0.2 offset gives it
  239.                 // a slight upward drift)
  240.                 dValue += 2 * m_r.nextGaussian() + 0.2;
  241.                 AddValue(dValue);
  242.                 
  243.                 // now repaint the window
  244.                 repaint();
  245.  
  246.                 // repaint at the fps speed
  247.                 Thread.sleep(nSleepTime);
  248.             }
  249.             catch (InterruptedException e)
  250.             {
  251.                 stop();
  252.             }
  253.         }
  254.     }
  255.  
  256.     // ResizeArray - resize the array of stock prices
  257.     //               (if necessary)
  258.     private void ResizeArray(int nWidth)
  259.     {
  260.         // if the window is the same size...
  261.         int nNumPts = XToIndex(nWidth);
  262.         if (nNumPts == m_nSize)
  263.         {
  264.             // ...then ignore it
  265.             return;
  266.         }
  267.  
  268.         // otherwise, we need to resize the array:
  269.         // allocate room
  270.         double[] dNewArray = new double[nNumPts];
  271.  
  272.         // now copy the points from the old, smaller
  273.         // array to the new, larger array
  274.         int nNumToCopy = Math.min(nNumPts, m_nSize);
  275.         for (int i = 0; i < nNumToCopy; i++)
  276.         {
  277.             dNewArray[i] = m_dValue[i];
  278.         }
  279.  
  280.         // finally, make the new array our own
  281.         m_dValue = dNewArray;
  282.         m_nSize = nNumPts;
  283.     }
  284.  
  285.     // AddValue - add a value to the array
  286.     synchronized private void AddValue(double dValue)
  287.     {
  288.         // indicate to update how far we've moved the
  289.         // data points over since the last time it repainted
  290.         m_nOffset++;
  291.  
  292.         // move everything over one to make
  293.         // room for the new data item
  294.         for (int i = m_nSize - 1; i > 0; i--)
  295.         {
  296.             m_dValue[i] = m_dValue[i - 1];
  297.         }
  298.  
  299.         // add the new data item as the
  300.         // the first entry
  301.         m_dValue[0] = dValue;
  302.  
  303.         // make sure to keep track of the max
  304.         while (dValue >= m_nMax)
  305.         {
  306.             m_nMax += 50;
  307.         }
  308.     }
  309.  
  310.     // XToIndex - convert the display window dimension
  311.     //            to the corresponding array index
  312.     private static final int m_PIXELS_PER_POINT = 3;
  313.     static private int XToIndex(int nWidth)
  314.     {
  315.         return nWidth / m_PIXELS_PER_POINT;
  316.     }
  317.     // IndexToX - convert the array index to the window
  318.     //            x offset
  319.     static private int IndexToX(int nWidth, int nIndex)
  320.     {
  321.         return (nWidth - 1) - (m_PIXELS_PER_POINT * nIndex);
  322.     }
  323.     // ValueToY - convert the stock value to the y
  324.     //            offset in the window to plot the point
  325.     private int ValueToY(int nHeight, double dValue)
  326.     {
  327.         return nHeight - ((int)dValue * nHeight) / m_nMax;
  328.     }
  329. }
  330.