home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / inprise / JHELP.Z / StockApplet.java < prev    next >
Text File  |  1998-05-08  |  11KB  |  356 lines

  1. /*
  2.  * Copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
  3.  *
  4.  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
  5.  * modify and redistribute this software in source and binary code form,
  6.  * provided that i) this copyright notice and license appear on all copies of
  7.  * the software; and ii) Licensee does not utilize the software in a manner
  8.  * which is disparaging to Sun.
  9.  *
  10.  * This software is provided "AS IS," without a warranty of any kind. ALL
  11.  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
  12.  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  13.  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
  14.  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
  15.  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
  16.  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
  17.  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
  18.  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
  19.  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
  20.  * POSSIBILITY OF SUCH DAMAGES.
  21.  *
  22.  * This software is not designed or intended for use in on-line control of
  23.  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
  24.  * the design, construction, operation or maintenance of any nuclear
  25.  * facility. Licensee represents and warrants that it will not use or
  26.  * redistribute the Software for such purposes.
  27.  */
  28.  
  29. package examples.stock;
  30.  
  31. import java.applet.Applet;
  32. import java.awt.*;
  33. import java.net.URL;
  34. import java.rmi.*;
  35. import java.rmi.server.*;
  36. import java.util.*;
  37.  
  38. /**
  39.  * The StockApplet exports a remote object, and contacts the StockWatch
  40.  * server to register interest in receiving stock updates.  The applet
  41.  * displays the updates in a graph format.
  42.  */
  43. public class StockApplet extends Applet
  44.     implements StockNotify, java.io.Serializable
  45. {
  46.     /** maximum number of updates displayed */
  47.     static final int MAX_UPDATES = 34;
  48.     /** maximum width of panel */
  49.     private static final int width  = 500;
  50.     /** maximum height of panel */
  51.     private static final int height = 350;
  52.  
  53.     /** vector containing time of each update */
  54.     private Vector time = new Vector(MAX_UPDATES);
  55.     /** table mapping stock names to stock data */
  56.     private Hashtable stockTable = new Hashtable();
  57.     /** reference to StockWatch server */
  58.     private StockWatch stockWatch = null;
  59.     
  60.     private String name[] = { "Sun", "HP", "Microsoft", "DEC","Novell",
  61.                   "IBM","Apple","Netscape","Borland","SGI"};
  62.     private Color color[]= { new Color(205,92,92),
  63.                  Color.orange,
  64.                  new Color(220,220,90),
  65.                  new Color(85, 107, 47),
  66.                  Color.blue,
  67.                  new Color(160,32,240),
  68.                  new Color(238, 130, 238),
  69.                  Color.black,
  70.                  new Color(205,120,92),
  71.                  new Color(0,100,0) };
  72.     
  73.     /**
  74.      * Notification of stock updates for a particular time.
  75.      * @param date the time of the stock update
  76.      * @param stocks an array containing the stocks for which the
  77.      * object has registered interest.
  78.      */
  79.     public void update (Date date, Stock[] stock) 
  80.     {
  81.     System.out.println("StockApplet.update: " + date);
  82.     // record date
  83.     if (time.size() == MAX_UPDATES) { 
  84.         time.removeElementAt(0);
  85.     }
  86.     time.addElement(date);
  87.  
  88.     // record individual stock updates
  89.     int numUpdates = time.size();
  90.     for (int i=0; i<stock.length; i++) {
  91.         StockData data = (StockData)stockTable.get(stock[i].symbol);
  92.         if (data != null) {
  93.         data.update(stock[i], numUpdates);
  94.         }
  95.     }
  96.     repaint();
  97.     }
  98.  
  99.     /**
  100.      * Initialize applet: export the applet as remote object that gets
  101.      * notified of stock updates.
  102.      */
  103.     public void init() 
  104.     {
  105.     try {
  106.         // export the applet as a remote object
  107.         System.out.println("StockApplet.init: exporting remote object");
  108.         UnicastRemoteObject.exportObject(this);
  109.         
  110.         // lookup StockWatch server
  111.         URL base = getDocumentBase();
  112.         String serverName = "//" + base.getHost() + ":" +
  113.         getParameter("registryPort") + "/example.stock.StockServer";
  114.         
  115.         System.out.println("StockApplet.init: looking up server");
  116.         stockWatch = (StockWatch)Naming.lookup(serverName);
  117.  
  118.         // register interest in receiving stock updates
  119.         for (int i=0; i<name.length; i++) {
  120.         System.out.println("StockApplet.init: watch stock " + name[i]);
  121.         stockWatch.watch(name[i], this);
  122.         stockTable.put(name[i], new StockData(name[i], color[i]));
  123.         }
  124.         System.out.println("StockApplet.init: done registering stocks");
  125.         
  126.     } catch (Exception e) {
  127.         // fatal error
  128.         System.out.println("got exception: " + e.getMessage());
  129.         e.printStackTrace();
  130.         return;
  131.     }
  132.  
  133.         setLayout(null);
  134.  
  135.     // draw checkboxes
  136.     Enumeration enum =  stockTable.elements();
  137.     int i=0; 
  138.     while (enum.hasMoreElements()) {
  139.         StockData data = (StockData)enum.nextElement();
  140.             SensitiveCheckbox cb = new SensitiveCheckbox (data, this);
  141.             data.cb = cb;
  142.             add(cb);
  143.             cb.setState(data.displayed);
  144.             cb.reshape(10,i++*25+35,110,18);
  145.         }
  146.     }
  147.  
  148.     /**
  149.      * Called when applet is destroyed; the applet cancels all
  150.      * requests for stock updates.
  151.      */
  152.     public void destroy() 
  153.     {
  154.     // cancel request for stock updates
  155.     if (stockWatch != null) {
  156.         try {
  157.         stockWatch.cancelAll(this);
  158.         } catch (Exception e) {
  159.         // eat exception
  160.         }
  161.     }
  162.     }
  163.  
  164.     /**
  165.      * Called to repaint the panel.
  166.      */
  167.     public void paint(Graphics g) {
  168.  
  169.         // draw black boarder
  170.         g.setColor(Color.black);
  171.         g.drawRect(0,0,width-1,height-1);
  172.  
  173.         float miny = 0.0f;
  174.         float maxy = 75.0f;
  175.  
  176.     // draw all stock data
  177.     Enumeration enum = stockTable.elements();
  178.     while (enum.hasMoreElements()) {
  179.         StockData data = (StockData)enum.nextElement();
  180.  
  181.             int size;
  182.             Stock[] updates;
  183.             synchronized (data.updates) {
  184.                 size = data.updates.size();
  185.                 updates = new Stock[size];
  186.                 data.updates.copyInto(updates);
  187.             }
  188.         
  189.             g.setColor(data.color);
  190.  
  191.             if (data.displayed) {
  192.         // draw box around checkbox if mouse is over it
  193.                 if (data.cb != null && data.cb.haveMouse()) {
  194.                     Point p = data.cb.location();
  195.                     Dimension d = data.cb.size();
  196.  
  197.                     g.drawRect(p.x-1, p.y-1, d.width+4, d.height+4);
  198.                     g.drawRect(p.x-2, p.y-2, d.width+4, d.height+4);
  199.             // point to graph for stock
  200.                     if (size > 0)
  201.                         g.drawLine(p.x+d.width+2,p.y+10,150,
  202.                                    scale(updates[0].current));
  203.                 }
  204.         // draw graph of updates for this stock
  205.                 int x = 150, inc = 10;
  206.                 for (int i = 0; i < size; i++) {
  207.                     if (updates[i] != null) {
  208.                         g.drawRect(x-1,scale(updates[i].current)-1,3,3);
  209.                         if ((i < size - 1) && updates[i + 1] != null) {
  210.                             int x2 = x + inc;
  211.                             g.drawLine(x, scale(updates[i].current), x2,
  212.                                        scale(updates[i + 1].current));
  213.                         }
  214.                     }
  215.             x += inc;
  216.         }
  217.         }
  218.         }
  219.     }
  220.  
  221.     /**
  222.      * Used to scale y-values.
  223.      */
  224.     int scale(float y) {
  225.         return height - (int) (y*5+.5);
  226.     }
  227.  
  228.     /**
  229.      * Make sure that mouseHere is set properly (fix for windows
  230.      * display problems).
  231.      */
  232.     void setMouseHere(boolean display) 
  233.     {
  234.     Enumeration enum = stockTable.elements();
  235.     while (enum.hasMoreElements()) {
  236.         StockData data = (StockData)enum.nextElement();
  237.         data.cb.mouseHere = display;
  238.     }
  239.     }
  240. }
  241.  
  242. /**
  243.  * StockData contains stock updates and display information.
  244.  */
  245. class StockData {
  246.     public String name;
  247.     public Vector updates;
  248.     public Color color;
  249.     public boolean displayed;
  250.     public SensitiveCheckbox cb;
  251.  
  252.     public StockData(String name, Color cl) {
  253.         this.name = name;
  254.         this.color = cl;
  255.     this.updates = new Vector(StockApplet.MAX_UPDATES);
  256.         displayed = true;
  257.     }
  258.  
  259.     /**
  260.      * Update stock.
  261.      */
  262.     void update(Stock stock, int numUpdates) 
  263.     {
  264.         synchronized (updates) {
  265.             if (updates.size() == StockApplet.MAX_UPDATES) {
  266.                 updates.removeElementAt(0);
  267.             }
  268.             // If this stock has not received updates for previous timeslices,
  269.             // fill them in with the current update value as well.
  270.             if (updates.size() < numUpdates) {
  271.                 for (int i=updates.size(); i<numUpdates-1; i++) {
  272.                     updates.addElement(stock);
  273.                 }
  274.             }
  275.             updates.addElement(stock);
  276.         }
  277.     }
  278. }
  279.  
  280. /**
  281.  * A mouse-sensitive checkbox that records whether the mouse is over
  282.  * the checkbox.
  283.  */
  284. class SensitiveCheckbox extends Canvas {
  285.     StockData data;
  286.     boolean state = true;
  287.     StockApplet panel;
  288.     boolean mouseHere = false;
  289.  
  290.     public boolean haveMouse() {
  291.         return mouseHere;
  292.     }
  293.  
  294.     public SensitiveCheckbox(StockData data, StockApplet p) {
  295.         this.data = data;
  296.         panel = p;
  297.     }
  298.  
  299.     public boolean mouseEnter(Event evt, int x, int y) {
  300.         if (state) {
  301.         panel.setMouseHere(false); // for windows
  302.             mouseHere = true;
  303.             panel.repaint();
  304.         }
  305.         return false;
  306.     }
  307.     public boolean mouseExit(Event evt, int x, int y) {
  308.         if (state) {
  309.             mouseHere = false;
  310.             panel.repaint();
  311.         }
  312.         return false;
  313.     }
  314.  
  315.     public boolean mouseDown(Event evt, int x, int y) {
  316.         if (state)
  317.             state = false;
  318.         else
  319.             state = true;
  320.         mouseHere=state;
  321.         data.displayed = state;
  322.         repaint();
  323.         panel.repaint();
  324.         return true;
  325.     }
  326.  
  327.     public void paint(Graphics g) {
  328.         g.setColor(Color.black);
  329.         g.drawLine(4,4,14,4);
  330.         g.drawLine(4,4,4,14);
  331.         g.setColor(Color.gray);
  332.         g.drawLine(5,14,14,14);
  333.         g.drawLine(14,5,14,14);
  334.         g.setColor(data.color);
  335.         g.fillRect(5,5,8,8);
  336.         g.setColor(data.color);
  337.         g.drawString(data.name, 17,15);
  338.         g.setColor(Color.black);
  339.         if (state) {
  340.             if (data.color == Color.black)
  341.                 g.setColor(Color.gray);
  342.             if (data.color == Color.blue)
  343.                 g.setColor(Color.gray);
  344.             g.drawLine(5,5,13,13);
  345.             g.drawLine(5,6,12,13);
  346.             g.drawLine(13,5,5,13);
  347.             g.drawLine(13,6,6,13);
  348.         }
  349.     }
  350.  
  351.     public void setState(boolean s) {
  352.         state = s;
  353.         repaint();
  354.     }
  355. }
  356.