home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / win95 / sieciowe / hotja32.lzh / hotjava / classsrc / browser / progresswindow.java < prev    next >
Text File  |  1995-08-11  |  8KB  |  297 lines

  1. /*
  2.  * @(#)ProgressWindow.java    1.6 95/08/04 Chris Warth
  3.  *
  4.  * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19. package browser;
  20.  
  21. import awt.*;
  22. import net.ProgressEntry;
  23. import net.ProgressData;
  24. import browser.Observer;
  25. import browser.Observable;
  26. import browser.ProgressBusy;
  27.  
  28. public class ProgressWindow extends Window implements Observer {
  29.     static Font    dialogFont;
  30.     static FontMetrics fontmetrics;
  31.     static Font    legendFont;
  32.     static int fontheight;
  33.     static int entryheight;
  34.  
  35.     static final int KLIMIT     = (10 * 1024);
  36.     static final int lmargin     = 10;
  37.     static final int barheight  = 12;
  38.     static final int ystart     = 35;
  39.  
  40.     static Color colors[] = {
  41.     new Color(50, 220, 100),
  42.     new Color(220, 100, 50),
  43.     new Color(100, 120, 240),
  44.     new Color(200, 120, 240),
  45.     new Color(220, 240, 100),
  46.     Color.lightGray
  47.     };
  48.     static String names[] = {
  49.     "html",
  50.     "image",
  51.     "class",
  52.     "audio",
  53.     "other",
  54.     "connecting",
  55.     };
  56.  
  57.     ProgressBusy busyloop; //= new ProgressBusy(this);
  58.  
  59.     /**
  60.      * Construct a progress window.
  61.      */
  62.     ProgressWindow(Container w, String name, Color bg, int wd, int ht) {
  63.     super(w, name, bg, wd, ht);
  64.     ProgressData.pdata.addObserver(this);
  65.     }
  66.  
  67.     /*
  68.      * This class is an observer of ProgressData.  There are
  69.      * essentially three types of updates that are expected; an entry
  70.      * may be created or deleted, or the values of an entry can be
  71.      * updated.
  72.      */
  73.     public synchronized void update(Observable o) {
  74.     if ((dialogFont == null) || !mapped) {
  75.         return;
  76.     }
  77.  
  78.     Graphics g = new Graphics(this);
  79.  
  80.     try {
  81.         ProgressData pd = (ProgressData)o;
  82.         int id = pd.lastchanged;
  83.         g.clipRect(lmargin, 0, width - lmargin*2, height);
  84.  
  85.         switch (pd.what) {
  86.         case ProgressData.NEW:
  87.         paint(g, id, pd.streams[id]);
  88.         if (busyloop != null) {
  89.             busyloop.wakeUp();
  90.         }
  91.         break;
  92.         
  93.         case ProgressData.CONNECTED:
  94.         eraseEntry(g, id);
  95.         paint(g, id, pd.streams[id]);
  96.         break;
  97.  
  98.         case ProgressData.UPDATE:
  99.         paintUpdate(g, id, pd.streams[id]);
  100.         break;
  101.  
  102.         case ProgressData.DELETE:
  103.         eraseEntry(g, id);
  104.         break;
  105.         }
  106.     } catch (Exception e) {
  107.         e.printStackTrace();
  108.     } finally {
  109.         g.dispose();
  110.     }
  111.     }
  112.  
  113.     /**
  114.      * Erase an entry
  115.      */
  116.     void eraseEntry(Graphics g, int id) {
  117.     int barw = width-(2*lmargin);        // outside bar width.
  118.  
  119.     g.setForeground(background);
  120.     g.fillRect(lmargin, ystart + (id*entryheight), barw, entryheight);
  121.     //g.setForeground(Color.gray);
  122.     //g.drawRect(lmargin, ystart + fontheight + (id*entryheight), barw-1, barheight);
  123.     }
  124.  
  125.  
  126.     /**
  127.      * Paint an entry
  128.      */
  129.     void paint(Graphics g, int id, ProgressEntry te) {
  130.     // Draw the title of this bar
  131.     if (te.label != null) {
  132.         String str = te.label;
  133.  
  134.         g.setFont(dialogFont);
  135.         g.setForeground(Color.black);
  136.         g.drawString(str, lmargin, ystart + (id * entryheight) + 
  137.                         fontmetrics.height - (fontmetrics.descent + 1));
  138.  
  139.         if (te.connected) {
  140.         int x = lmargin + fontmetrics.stringWidth(str) + 10;
  141.  
  142.         if (te.need >= KLIMIT) {
  143.             str = String.valueOf(te.need / 1024) + " Kb";
  144.         } else {
  145.             str = String.valueOf(te.need) + " bytes";
  146.         }
  147.  
  148.         x = Math.max(x, (width - lmargin) - fontmetrics.stringWidth(str));
  149.         g.drawString(str, x, ystart + (id * entryheight) + 
  150.                         fontmetrics.height - (fontmetrics.descent + 1));
  151.         }
  152.     }
  153.  
  154.     // Draw the bar
  155.     paintUpdate(g, id, te);
  156.     }
  157.  
  158.  
  159.     /**
  160.      * Paint busy signal.
  161.      */
  162.     public synchronized void busyPaint(int id, int oldpos, int newpos) {
  163.     if (mapped) {
  164.         Graphics g = new Graphics(this);
  165.         try {
  166.         busyPaint(g, id, oldpos, newpos);
  167.         } finally {
  168.         g.dispose();
  169.         }
  170.     }
  171.     }
  172.  
  173.     /*
  174.      * This is called every now and then to move a small bar back
  175.      * and forth across the status bar to indicate that the
  176.      * connection is still in progress.  The driver behind this is
  177.      * the thread created by the ProgressBusy class.
  178.      */
  179.     void busyPaint(Graphics g, int id, int oldpos, int newpos) {
  180.     int barw = width-(2*lmargin);        // outside bar width.
  181.     int innerbarw = barw-2;            // inside bar width.
  182.     int busyw = (int) ((float) barw * .07); // width of floating busy indicator
  183.     int busybarw = innerbarw - busyw;        // width in which to move busy indicator
  184.  
  185.     // First erase the old indicator
  186.     g.setForeground(background);
  187.     g.fillRect(lmargin + 1 + (int)(((float)oldpos/100.0) * busybarw), 
  188.          ystart + fontheight + (id*entryheight) + 1,
  189.          busyw, barheight - 1);
  190.  
  191.     // Now draw the new indicator.
  192.     g.setForeground(Color.gray);
  193.     g.fillRect(lmargin + 1 + (int)(((float)newpos/100.0) * busybarw), 
  194.          ystart + fontheight + (id*entryheight) + 1,
  195.          busyw, barheight - 1);
  196.  
  197.     }
  198.  
  199.     /**
  200.      * Update an entry.
  201.      */
  202.     void paintUpdate(Graphics g, int id, ProgressEntry te) {
  203.     int barw = width-(2*lmargin);        // outside bar width.
  204.     int y = ystart + fontheight + id*entryheight;
  205.     int ww = (int)((((float) barw)/te.need)*te.read);
  206.  
  207.     g.setForeground(Color.black);
  208.     g.drawRect(lmargin, y, barw-1, barheight);
  209.  
  210.     g.setForeground(colors[te.type]);
  211.     g.fillRect(lmargin + 1, y+1, ww - 1, barheight-1);
  212.  
  213. //    g.setForeground(background);
  214. //    g.fillRect(ww + lmargin + 1, y+1, (barw - 2) - ww, barheight-1);
  215.  
  216.     }
  217.  
  218.     /**
  219.      * Paint the legend (at the top of the window)
  220.      */
  221.     void paintLegend(Graphics g) {
  222.     // initialize the font
  223.     if (legendFont == null) {
  224.         legendFont = wServer.fonts.getFont("Dialog", Font.PLAIN, 12);
  225.             /* The following is a workaround for an unknown bug.
  226.                Without it, the font is blank on NT 3.5 */
  227.         g.getFontMetrics(legendFont);
  228.     }
  229.  
  230.     // Set the font
  231.     g.setFont(legendFont);
  232.  
  233.     // Draw the legend
  234.     int x = lmargin;
  235.     for (int i = 0; i < colors.length; i++) {
  236.         g.setForeground(colors[i]);
  237.         g.fillRect(x + 1, 6, 13, 13);
  238.         g.setForeground(Color.black);
  239.         g.drawRect(x, 5, 14, 14);
  240.         x += 15 + 3;
  241.         x += g.drawStringWidth(names[i], x, 17) + 10;
  242.     }
  243.  
  244.     // draw a horizontal indented line.
  245.     g.paint3DRect(0, 25, width, 2, false, false);
  246.     }
  247.  
  248.     void paint(Graphics g) {
  249.     /*
  250.      * It is *REALLY* irritating that you cannot create fonts,
  251.      * etc, until after the window is actually mapped to the
  252.      * screen.  This torques around the design of this class
  253.      * quite a bit.
  254.      */
  255.     if (dialogFont == null) {
  256.         dialogFont = wServer.fonts.getFont("Dialog", Font.ITALIC, 10);
  257.         fontmetrics = g.getFontMetrics(dialogFont);
  258.         fontheight = dialogFont.actualHeight;
  259.         entryheight = barheight + fontmetrics.height + 5;
  260.     }
  261.  
  262.     paintLegend(g);
  263.  
  264.     ProgressData pd = ProgressData.pdata;
  265.     g.clipRect(lmargin, 0, width - lmargin*2, height);
  266.     g.setFont(dialogFont);
  267.     for (int i = 0; i < pd.streams.length; i++) {
  268.         ProgressEntry te = pd.streams[i];
  269.         if (te != null) {
  270.         if (te.need == te.read && te.read != 0) {
  271.             eraseEntry(g, i);
  272.         } else {
  273.             paint(g, i, te);
  274.         }
  275.         } else {
  276.         eraseEntry(g, i);
  277.         }
  278.     }
  279.     }
  280.  
  281.     /**
  282.      * Paint the progess dialog from scratch.
  283.      */
  284.     synchronized public void paint() {
  285.     Graphics g = new Graphics(this);
  286.     try {
  287.         g.setForeground(background);
  288.         g.fillRect(0, 0, width, height);
  289.         paint(g);
  290.     } catch (Exception e) {
  291.         e.printStackTrace();
  292.     } finally {
  293.         g.dispose();
  294.     }
  295.     }
  296. }
  297.