home *** CD-ROM | disk | FTP | other *** search
/ Internet News 1999 October / INEWS_10_CD.ISO / pc / jdk / jdk1.2.2 / docs / guide / rmi / examples / stock / StockApplet.java < prev    next >
Encoding:
Java Source  |  1999-09-19  |  11.0 KB  |  392 lines

  1. /*
  2.  * Copyright (c) 1996,1997,1998,1999
  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 = null;
  55.     /** vector to hold references to checkboxes */
  56.     private Vector checkboxes = null;
  57.     /** table mapping stock names to stock data */
  58.     private Hashtable stockTable = null;
  59.     /** reference to StockWatch server */
  60.     private StockWatch stockWatch = null;
  61.  
  62.     private static String name[] = { "Sun", "HP", "Microsoft", "Compaq", "Novell",
  63.                      "IBM", "Apple", "AOL", "Inprise", "SGI"};
  64.  
  65.     private Color color[]= { new Color(205,92,92),
  66.                  Color.orange,
  67.                  new Color(220,220,90),
  68.                  new Color(85, 107, 47),
  69.                  Color.blue,
  70.                  new Color(160,32,240),
  71.                  new Color(238, 130, 238),
  72.                  Color.black,
  73.                  new Color(205,120,92),
  74.                  new Color(0,100,0) };
  75.     
  76.     /**
  77.      * Notification of stock updates for a particular time.
  78.      * @param date the time of the stock update
  79.      * @param stocks an array containing the stocks for which the
  80.      * object has registered interest.
  81.      */
  82.     public synchronized void update (Date date, Stock[] stock) 
  83.     {
  84.     System.out.println("StockApplet.update: " + date);
  85.     // record date
  86.     if (time.size() == MAX_UPDATES) { 
  87.         time.removeElementAt(0);
  88.     }
  89.     time.addElement(date);
  90.  
  91.     // record individual stock updates
  92.     int numUpdates = time.size();
  93.     for (int i=0; i<stock.length; i++) {
  94.         StockData data = (StockData)stockTable.get(stock[i].symbol);
  95.         if (data != null) {
  96.         data.update(stock[i], numUpdates);
  97.         }
  98.     }
  99.     repaint();
  100.     }
  101.  
  102.     /**
  103.      * Initialize applet: export the applet as a remote object that 
  104.      * gets notified of stock updates.
  105.      */
  106.     public void init() 
  107.     {
  108.     // record export exception
  109.     Exception ee = null;
  110.  
  111.     try {
  112.         // initialize applet fields here to properly handle a restart
  113.         synchronized (this) {
  114.         time = new Vector(MAX_UPDATES);
  115.         stockTable = new Hashtable();
  116.         stockWatch = null;
  117.         }
  118.  
  119.         // export the applet as a remote object
  120.         System.out.println("StockApplet.init: exporting remote object");
  121.         try {
  122.         UnicastRemoteObject.exportObject(this);
  123.         ee = null;
  124.         } catch (java.rmi.server.ExportException e) {
  125.         // use already exported object; remember exception
  126.         ee = e;
  127.         }
  128.         
  129.         // lookup StockWatch server
  130.         URL base = getDocumentBase();
  131.         String serverName = "//" + base.getHost() + ":" +
  132.         getParameter("registryPort") + "/example.stock.StockServer";
  133.         
  134.         System.out.println("StockApplet.init: looking up server");
  135.         stockWatch = (StockWatch)Naming.lookup(serverName);
  136.  
  137.         // register interest in receiving stock updates
  138.         for (int i=0; i<name.length; i++) {
  139.         System.out.println("StockApplet.init: watch stock " + name[i]);
  140.         stockWatch.watch(name[i], this);
  141.         stockTable.put(name[i], new StockData(name[i], color[i]));
  142.         }
  143.         System.out.println("StockApplet.init: done registering stocks");
  144.         
  145.     } catch (Exception e) {
  146.         add(new Label("exception occurred during initialization; " +
  147.               "check the log"));
  148.         add(new Label(e.getClass().getName() + ": " + e.getMessage()));
  149.         
  150.         // fatal error
  151.         System.out.println("got exception: " + e.getMessage());
  152.         e.printStackTrace();
  153.         return;
  154.     }
  155.  
  156.         setLayout(null);
  157.  
  158.     // clean up after previous run, remove old checkboxes
  159.     if ((ee != null) && (checkboxes != null)) {
  160.         Enumeration oldCheckboxes = checkboxes.elements();
  161.         while (oldCheckboxes.hasMoreElements()) {
  162.         SensitiveCheckbox cb = (SensitiveCheckbox)
  163.             oldCheckboxes.nextElement();
  164.         remove(cb);
  165.         }
  166.     }
  167.  
  168.     // draw checkboxes
  169.     checkboxes = new Vector();
  170.     Enumeration enum = stockTable.elements();
  171.     int i=0; 
  172.     while (enum.hasMoreElements()) {
  173.         StockData data = (StockData)enum.nextElement();
  174.         SensitiveCheckbox cb = new SensitiveCheckbox (data, this);
  175.         data.cb = cb;
  176.         checkboxes.add(cb);
  177.         add(cb);
  178.         cb.setState(data.displayed);
  179.         cb.reshape(10,i++*25+35,110,18);
  180.     }
  181.     }
  182.  
  183.     /**
  184.      * Called when applet is destroyed; the applet cancels all
  185.      * requests for stock updates.
  186.      */
  187.     public void destroy() 
  188.     {
  189.     // cancel request for stock updates
  190.     if (stockWatch != null) {
  191.         try {
  192.         stockWatch.cancelAll(this);
  193.         } catch (Exception e) {
  194.         // eat exception
  195.         }
  196.     }
  197.     }
  198.  
  199.     /**
  200.      * Called to repaint the panel.
  201.      */
  202.     public void paint(Graphics g) {
  203.  
  204.         // draw black boarder
  205.         g.setColor(Color.black);
  206.         g.drawRect(0,0,width-1,height-1);
  207.  
  208.         float miny = 0.0f;
  209.         float maxy = 75.0f;
  210.  
  211.     // draw all stock data
  212.     Enumeration enum = stockTable.elements();
  213.     while (enum.hasMoreElements()) {
  214.         StockData data = (StockData)enum.nextElement();
  215.  
  216.             int size;
  217.             Stock[] updates;
  218.             synchronized (data.updates) {
  219.                 size = data.updates.size();
  220.                 updates = new Stock[size];
  221.                 data.updates.copyInto(updates);
  222.             }
  223.         
  224.             g.setColor(data.color);
  225.  
  226.             if (data.displayed) {
  227.         // draw box around checkbox if mouse is over it
  228.  
  229.                 if (data.cb != null && data.cb.haveMouse()) {
  230.                     Point p = data.cb.location();
  231.                     Dimension d = data.cb.size();
  232.  
  233.                     g.drawRect(p.x-1, p.y-1, d.width+4, d.height+4);
  234.                     g.drawRect(p.x-2, p.y-2, d.width+4, d.height+4);
  235.             // point to graph for stock
  236.             if (size > 0)
  237.                         g.drawLine(p.x+d.width+2,p.y+10,150,
  238.             scale(updates[0].current));
  239.                 }
  240.         // draw graph of updates for this stock
  241.                 int x = 150, inc = 10;
  242.                 for (int i = 0; i < size; i++) {
  243.                     if (updates[i] != null) {
  244.                         g.drawRect(x-1,scale(updates[i].current)-1,3,3);
  245.                         if ((i < size - 1) && updates[i + 1] != null) {
  246.                             int x2 = x + inc;
  247.                             g.drawLine(x, scale(updates[i].current), x2,
  248.                                        scale(updates[i + 1].current));
  249.                         }
  250.                     }
  251.             x += inc;
  252.         }
  253.         }
  254.         }
  255.     }
  256.  
  257.     /**
  258.      * Used to scale y-values.
  259.      */
  260.     int scale(float y) {
  261.         return height - (int) (y*5+.5);
  262.     }
  263.  
  264.     /**
  265.      * Make sure that mouseHere is set properly (fix for windows
  266.      * display problems).
  267.      */
  268.     void setMouseHere(boolean display) 
  269.     {
  270.     Enumeration enum = stockTable.elements();
  271.     while (enum.hasMoreElements()) {
  272.         StockData data = (StockData)enum.nextElement();
  273.         data.cb.mouseHere = display;
  274.     }
  275.     }
  276.  
  277.     /**
  278.      * StockData contains stock updates and display information.
  279.      */
  280.     static class StockData {
  281.     public String name;
  282.     public Vector updates;
  283.     public Color color;
  284.     public boolean displayed;
  285.     public SensitiveCheckbox cb;
  286.     
  287.     public StockData(String name, Color cl) {
  288.         this.name = name;
  289.         this.color = cl;
  290.         this.updates = new Vector(StockApplet.MAX_UPDATES);
  291.         displayed = true;
  292.     }
  293.     
  294.     /**
  295.      * Update stock.
  296.      */
  297.     void update(Stock stock, int numUpdates) {
  298.         synchronized (updates) {
  299.         if (updates.size() == StockApplet.MAX_UPDATES) {
  300.             updates.removeElementAt(0);
  301.         }
  302.         // If this stock has not received updates for previous timeslices,
  303.         // fill them in with the current update value as well.
  304.         if (updates.size() < numUpdates) {
  305.             for (int i=updates.size(); i<numUpdates-1; i++) {
  306.             updates.addElement(stock);
  307.             }
  308.         }
  309.         updates.addElement(stock);
  310.         }
  311.     }
  312.     }
  313.  
  314.     /**
  315.      * A mouse-sensitive checkbox that records whether the mouse is over
  316.      * the checkbox.
  317.      */
  318.     static class SensitiveCheckbox extends Canvas {
  319.     StockData data;
  320.     boolean state = true;
  321.     StockApplet panel;
  322.     boolean mouseHere = false;
  323.     
  324.     public boolean haveMouse() {
  325.         return mouseHere;
  326.     }
  327.     
  328.     public SensitiveCheckbox(StockData data, StockApplet p) {
  329.         this.data = data;
  330.         panel = p;
  331.     }
  332.     
  333.     public boolean mouseEnter(Event evt, int x, int y) {
  334.         if (state) {
  335.         panel.setMouseHere(false); // for windows
  336.         mouseHere = true;
  337.         panel.repaint();
  338.         }
  339.         return false;
  340.     }
  341.  
  342.     public boolean mouseExit(Event evt, int x, int y) {
  343.         if (state) {
  344.         mouseHere = false;
  345.         panel.repaint();
  346.         }
  347.         return false;
  348.     }
  349.     
  350.     public boolean mouseDown(Event evt, int x, int y) {
  351.         if (state)
  352.         state = false;
  353.         else
  354.         state = true;
  355.         mouseHere=state;
  356.         data.displayed = state;
  357.         repaint();
  358.         panel.repaint();
  359.         return true;
  360.     }
  361.     
  362.     public void paint(Graphics g) {
  363.         g.setColor(Color.black);
  364.         g.drawLine(4,4,14,4);
  365.         g.drawLine(4,4,4,14);
  366.         g.setColor(Color.gray);
  367.         g.drawLine(5,14,14,14);
  368.         g.drawLine(14,5,14,14);
  369.         g.setColor(data.color);
  370.         g.fillRect(5,5,8,8);
  371.         g.setColor(data.color);
  372.         g.drawString(data.name, 17,15);
  373.         g.setColor(Color.black);
  374.         if (state) {
  375.         if (data.color == Color.black)
  376.             g.setColor(Color.gray);
  377.         if (data.color == Color.blue)
  378.             g.setColor(Color.gray);
  379.         g.drawLine(5,5,13,13);
  380.         g.drawLine(5,6,12,13);
  381.         g.drawLine(13,5,5,13);
  382.         g.drawLine(13,6,6,13);
  383.         }
  384.     }
  385.     
  386.     public void setState(boolean s) {
  387.         state = s;
  388.         repaint();
  389.     }
  390.     }
  391. }
  392.