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

  1. /*
  2.  * @(#)Applet.java    1.35 95/05/13 Chris Warth, Arthur van Hoff
  3.  *
  4.  * Copyright (c) 1994 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 java.io.*;
  22. import java.util.*;
  23. import awt.*;
  24. import net.www.html.*;
  25. import browser.audio.*;
  26.  
  27. /**
  28.  * Base applet class. All applets are subclasses of this class.
  29.  * Once the applet is loaded it is associated with an AppletDisplayItem
  30.  * in which it can draw. An applet's life is summarized by four methods:
  31.  * <dl>
  32.  * <dt>init()<dd>This method is called after the applet is created.
  33.  * The applet can use this method to resize itself, download resources, get fonts,
  34.  * get colors, etc.
  35.  * <dt>start()<dd>This method is called when the applet's document is visited.
  36.  * The applet can use this method to start a background thread for animation, to  play
  37.  * a sound etc.
  38.  * <dt>stop()<dd>This method is called when the applet's document is no longer on
  39.  * the screen. The applet should stop any thread it has forked and any long sounds
  40.  * that are playing. It is garanteed to be called before the applet is destroyed.
  41.  * <dt>destroy()<dd>This method is called when the applet is discarded. It is the
  42.  * last opportunity for the applet to clean up its act! Calls stop() if the applet
  43.  * is still active.
  44.  * </dl>
  45.  * When an applet is started it cannot directly draw to the screen. Instead it needs
  46.  * to call repaint(). This will cause the paint(Graphics) method of the applet to be
  47.  * called as soon as possible. This mechanism is needed so that the applet will not
  48.  * get confused when the document in which it is embedded is scrolled or resized.
  49.  * <p>
  50.  * The applet class contains various method that help you get images, get fonts,
  51.  * play audio, etc. If you can use these methods instead of doing the work yourself,
  52.  * they are more likely to be supported in the future.
  53.  * <p>
  54.  * Here is a very simple example of an applet.
  55.  * <pre>
  56.  *    import awt.*;
  57.  *    import browser.*;
  58.  *     public class HelloInternet extends Applet {
  59.  *        public void init() {
  60.  *        resize(150, 25);
  61.  *        }
  62.  *        public void paint(Graphics g) {
  63.  *        g.drawString("Hello Internet!", 5, 20);
  64.  *        }
  65.  *    }
  66.  * </pre>
  67.  * To try it out you need to add this in an html file.
  68.  * <pre>
  69.  *     <app class="HelloInternet">
  70.  * </pre>
  71.  * @see AppletDisplayItem
  72.  * @author Chris Warth
  73.  * @author Arthur van Hoff
  74.  * @version     1.35, 13 May 1995
  75.  */
  76. public
  77. class Applet {
  78.     boolean    inFocusList = false;
  79.       
  80.     /**
  81.      * The display item in which this applet is being displayed.
  82.      * Don't modify it.
  83.      */
  84.     public AppletDisplayItem item;
  85.  
  86.     /**
  87.      * The URL of the document in which the applet is embedded.
  88.      * Don't modify it.
  89.      */
  90.     public URL documentURL;
  91.  
  92.     /**
  93.      * The URL of the applet. This can differ from the documentURL
  94.      * when a "src" attribute is specified in the app tag.
  95.      * Don't modify it.
  96.      */
  97.     public URL appletURL;
  98.  
  99.     /**
  100.      * The tag. Use getAttribute() to get attributes in the tag.
  101.      * Don't modify it.
  102.      * @see Applet#getAttribute
  103.      */
  104.     public TagRef tag;
  105.  
  106.     /**
  107.      * The width of the applet. Use resize() to change the size of
  108.      * the applet and the display item in which it is located.
  109.      * You can change it by calling resize().
  110.      * @see Applet#resize
  111.      */
  112.     public int width;
  113.  
  114.     /**
  115.      * The height of the applet. Use resize() to change the size of
  116.      * the applet and the display item in which it is located.
  117.      * You can change it by calling resize().
  118.      * @see Applet#resize
  119.      */
  120.     public int height;
  121.  
  122.     /**
  123.      * The font of the applet. This font will be set when the paint()
  124.      * method is called. If you want to modify it, you need to do this
  125.      * in the init() method. This variable is initialized to an initial
  126.      * value, feel free to modify it.
  127.      * @see Applet#paint
  128.      * @see Applet#init
  129.      */
  130.     public Font font;
  131.  
  132.     /**
  133.      * The foreground color of the applet. This color will be the foreground
  134.      * color when the paint() method is called. This variable is initialized
  135.      * to an initial value, feel free to modify it.
  136.      * @see Applet#paint
  137.      */
  138.     public Color fgColor;
  139.  
  140.     /**
  141.      * The background color of the applet. This color is the background
  142.      * color of the window the applet is in when the applet was created.
  143.      *
  144.      * @see Applet#paint
  145.      */
  146.     public Color bgColor;
  147.  
  148.     /**
  149.      * Gets the parent, I know this is not great, but the formatter
  150.      * sometimes nukes the display item parent. I don't have time
  151.      * to fix the formatter so this is the best I can do!
  152.      */
  153.     private Window getParent() {
  154.     Window w = null;
  155.     while (((w = item.parent) == null) &&
  156.            ((item.getStatus() == AppletDisplayItem.STARTED) ||
  157.         (item.getStatus() == AppletDisplayItem.INITIALIZING))) {
  158.         Thread.currentThread().sleep(10);
  159.     }
  160.     return w;
  161.     }
  162.  
  163.     /**
  164.      * Repaints the applet, this will actually happen at
  165.      * some later time. To actually paint the applet HotJava
  166.      * will call the paint() method.
  167.      * @see Applet#paint
  168.      */
  169.     public void repaint() {
  170.     item.requestUpdate();
  171.     }
  172.  
  173.     /**
  174.      * Resizes the applet. You should resize the applet in the init() method.
  175.      * Resizing the applet at another time may cause the document to be reformatted.
  176.      * Don't worry about calling repaint(), resize will do the right thing for you.
  177.      * @see Applet#repaint
  178.      */
  179.     public void resize(int width, int height) {
  180.     if (this.width == width && this.height == height &&
  181.         item.width == width && item.height == height) {
  182.         // Avoid unnecessary relayouts.
  183.         // Some badly written Applets may accidentally set the
  184.         // width and height fields directly so both the Applet
  185.         // and the item demensions are checked.
  186.         return;
  187.     }
  188.     item.resize(width, height);
  189.     this.width = width;
  190.     this.height = height;
  191.  
  192.     // Any time other than during the init() method this
  193.     // will cause the document to be relayedout.
  194.     if ((item.getStatus() != AppletDisplayItem.INITIALIZING) && (item.parent != null)) {
  195.         ((browser.WRWindow)item.parent).relayout();
  196.     }
  197.     }
  198.  
  199.     /**
  200.      * Returns true if the applet is started. This will be true from just before
  201.      * start() is called until just after stop() is called.
  202.      */
  203.     public boolean isActive() {
  204.     return item.getStatus() == AppletDisplayItem.STARTED;
  205.     }
  206.  
  207.     /**
  208.      * Gets an attribute out of theapplet's app tag. Note that the
  209.      * width and height attributes are used to determine the initial
  210.      * dimensions of the applet.
  211.      * @return the attribute value or null if the attribute is not defined.
  212.      */
  213.     public String getAttribute(String name) {
  214.     return tag.getAttribute(name);
  215.     }
  216.  
  217.     /**
  218.      * Gets an image given an image name. The name is assumed to be
  219.      * relative to the appletURL. If the image can't be found there,
  220.      * the documentURL is  used.
  221.      * @return the image or null if something went wrong.
  222.      */
  223.     public Image getImage(String name) {
  224.     Image img = getImage(new URL(appletURL, name));
  225.     return (img != null) ? img : getImage(new URL(documentURL, name));
  226.     }
  227.  
  228.     /**
  229.      * Creates an image given a width and height. This is useful
  230.      * to do double-buffered graphics which can be done by creating a
  231.      * Graphics object that points to this image and then drawing
  232.      * directly to the image.
  233.      * @see awt#Graphics
  234.      * @return the image or null if something went wrong.
  235.      */
  236.     public Image createImage(int width, int height) {
  237.     Window parent = getParent();
  238.  
  239.     if (parent != null) {
  240.         return parent.createImage(width, height);
  241.     } else {
  242.         return null;
  243.     }
  244.     }
  245.  
  246.     /**
  247.      * Gets an image given a URL.
  248.      * @return the image or null if something went wrong.
  249.      */
  250.     public Image getImage(URL url) {
  251.     Window parent = getParent();
  252.     if (parent != null) {
  253.         try {
  254.         ImageHandle h = ImageCache.lookupHandle(parent, url);
  255.         Object img;
  256.  
  257.         img = h.getImage(null, true);
  258.         if (img instanceof Image) {
  259.             return (Image) img;
  260.         }
  261.         } catch (IOException ex) {
  262.         } catch (FileNotFoundException ex) {
  263.         }
  264.     }
  265.     return null;
  266.     }
  267.  
  268.     /**
  269.      * Gets audio data given a name. The name is assumed to be
  270.      * relative to the appletURL. If the data can't be found there,
  271.      * the documentURL is  used.
  272.      * @return the audio data or null if it could not be found.
  273.      * @see Applet#play
  274.      */
  275.     public AudioData getAudioData(String name) {
  276.     AudioData data = getAudioData(new URL(appletURL, name));
  277.     if (data == null) {
  278.         data = getAudioData(new URL(documentURL, name));
  279.     }
  280.     return data;
  281.     }
  282.  
  283.     /**
  284.      * Gets audio data given a url.
  285.      * @return the audio data or null if the URL is invalid.
  286.      * @see Applet#play
  287.      */
  288.     public AudioData getAudioData(URL url) {
  289.     try {
  290.         return AudioData.getAudioData(url);
  291.     } catch (IOException ex) {
  292.         return null;
  293.     } catch (FileNotFoundException ex) {
  294.         return null;
  295.     }
  296.     }
  297.  
  298.     /**
  299.      * Gets an audio stream given a url. The actual audio data
  300.      * can be very large because it will be read as the audio
  301.      * is being played.
  302.      * @return the stream or null if the URL is invalid.
  303.      * @see Applet#startPlaying
  304.      */
  305.     public InputStream getAudioStream(URL url) {
  306.     try {
  307.         return new AudioStream(url.openStream());
  308.     } catch (IOException ex) {
  309.         return null;
  310.     } catch (FileNotFoundException ex) {
  311.         return null;
  312.     }
  313.     }
  314.  
  315.     /**
  316.      * Gets a continuous audio stream given a URL. Note that
  317.      * all of the data will read before the stream can be used.
  318.      * @return the stream or null if the URL is invalid.
  319.      * @see Applet#startPlaying
  320.      */
  321.     public InputStream getContinuousAudioStream(URL url) {
  322.     AudioData data = getAudioData(url);
  323.     return (data != null) ? new ContinuousAudioDataStream(getAudioData(url)) : null;
  324.     }
  325.     
  326.     /**
  327.      * Plays an audio sample. The data is obtained using
  328.      * getAudioData(). Nothing happens if the data could not
  329.      * be found.
  330.      * @see Applet#getAudioData
  331.      */
  332.     public void play(String name) {
  333.     play(getAudioData(name));
  334.     }
  335.     
  336.     /**
  337.      * Plays an audio sample.
  338.      */
  339.     public void play(AudioData data) {
  340.     if (data != null) {
  341.         AudioPlayer.player.start(new AudioDataStream(data));
  342.     }
  343.     }
  344.     
  345.     /**
  346.      * Starts playing a stream of audio data. Use stopPlaying to
  347.      * stop the audio from playing.
  348.      * @see Applet#getAudioStream
  349.      * @see Applet#stopPlaying
  350.      */
  351.     public void startPlaying(InputStream stream) {
  352.     if (stream != null) {
  353.         AudioPlayer.player.start(stream);
  354.     }
  355.     }
  356.     
  357.     /**
  358.      * Stops playing a stream of audio data.
  359.      * @see Applet#startPlaying
  360.      */
  361.     public void stopPlaying(InputStream stream) {
  362.     if (stream != null) {
  363.         AudioPlayer.player.stop(stream);
  364.     }
  365.     }
  366.  
  367.     /**
  368.      * Shows a status string at the bottom of the HotJava window.
  369.      */
  370.     public void showStatus(String msg) {
  371.     if (item.parent != null) {
  372.         ((WRWindow)item.parent).status((msg != null) ? msg : "");
  373.     }
  374.     }
  375.  
  376.     /**
  377.      * Shows a Document.
  378.      */
  379.     public void showDocument(URL doc) {
  380.     if (item.parent != null) {
  381.         ((WRWindow)item.parent).pushURL(doc);
  382.     }
  383.     }
  384.  
  385.     /**
  386.      * Gets a font with the given  font name and size.
  387.      * @see awt.Font
  388.      */
  389.     public Font getFont(String name, int size) {
  390.     return getFont(name, Font.PLAIN, size);
  391.     }
  392.  
  393.     /**
  394.      * Gets a font with the given  font name, style, and size.
  395.      * @see awt.Font
  396.      */
  397.     public Font getFont(String name, int style, int size) {
  398.     Window parent = getParent();
  399.     Font f = null;
  400.     if (parent != null) {
  401.         f = parent.wServer.fonts.getFont(name, style, size);
  402.         parent.getFontMetrics(f);
  403.     }
  404.     return f;
  405.     }
  406.  
  407.     /**
  408.      * Gets the metrics for the given font.
  409.      * @see awt.FontMetrics
  410.      */
  411.     public FontMetrics getFontMetrics(Font font) {
  412.     Window parent = getParent();
  413.     if (parent != null) {
  414.         return parent.getFontMetrics(font);
  415.     }
  416.     return null;
  417.     }
  418.  
  419.     /**
  420.      * Gets a Color.
  421.      * @see awt.Color
  422.      */
  423.     public Color getColor(int r, int g, int b) {
  424.     Window parent = getParent();
  425.     if (parent != null) {
  426.         return new Color(parent.wServer, r, g, b);
  427.     }
  428.     return null;
  429.     }
  430.  
  431.     /**
  432.      * Initializes the applet.
  433.      * You never need to call this directly, it is called automatically
  434.      * by HotJava once the applet is created.
  435.      */
  436.     protected void init() {
  437.     }
  438.  
  439.     /**
  440.      * Called to start the applet. You never need to call this method
  441.      * directly it is called when the applet's document is visited.
  442.      * @see #stop
  443.      */
  444.     protected void start() {
  445.     }
  446.  
  447.     /**
  448.      * Called to stop the applet. It is called when the applet's document is
  449.      * no longer on the screen. It is guaranteed to be called before destroy()
  450.      * is called. You never need to call this method directly.
  451.      * @see #start
  452.      * @see #destroy
  453.      */
  454.     protected void stop() {
  455.     }
  456.  
  457.     /**
  458.      * Cleans up whatever resources are being held. If the applet is active
  459.      * it is first stopped.
  460.      * @see #stop
  461.      */
  462.     protected void destroy() {
  463.     }
  464.  
  465.     /**    
  466.      * Paints the applet, given a graphics context.
  467.      * The origin will be in the topleft corner of the applet.
  468.      * The clipping area is set to the exact size of the applet.
  469.      * The font, foreground color and  background color are set to
  470.      * default values.<p>
  471.      * <em>You never have to call this method explicitly!</e>
  472.      * It will be called automatically by HotJava in response
  473.      * to damage or expose events, or when you call repaint().
  474.      * @see Applet#repaint
  475.      */
  476.     public void paint(Graphics g) {
  477.     g.paint3DRect(0, 0, width, height, false, true);
  478.     }
  479.  
  480.     public void update(Graphics g) {
  481.     g.clearRect(0, 0, width, height);
  482.     paint(g);
  483.     }
  484.  
  485.     /**
  486.      * Mouse down. The x,y coordinates are relative to the
  487.      * applet's top left corner. A call to mouseUp() is
  488.      * guaranteed to follow when the mouse is released.
  489.      * mouseDrag is called when the mouse is moved.
  490.      * @see #mouseUp
  491.      * @see #mouseDrag
  492.      */
  493.     public void mouseDown(int x, int y) {
  494.     }
  495.  
  496.     /**
  497.      * Mouse drag (the mouse button is down). The x,y coordinates
  498.      * are relative to the applet's top left corner.
  499.      */
  500.     public void mouseDrag(int x, int y) {
  501.     }
  502.  
  503.     /**
  504.      * Mouse up. The x,y coordinates are relative to the
  505.      * applet's top left corner. This must have been preceded by
  506.      * a call to mouseDown().
  507.      * @see #mouseDown
  508.      */
  509.     public void mouseUp(int x, int y) {
  510.     }
  511.  
  512.     /**
  513.      * Mouse move (the mouse button is up). The x,y coordinates
  514.      * are relative to the applet's top left corner.
  515.      */
  516.     public void mouseMove(int x, int y) {
  517.     }
  518.  
  519.     /**
  520.      * Called when the mouse enters the applet (regardless of
  521.      * the mouse button state). A call to mouseExit is guaranteed
  522.      * to follow.
  523.      * @see #mouseExit
  524.      */
  525.     public void mouseEnter() {
  526.     }
  527.  
  528.     /**
  529.      * Called when the mouse exits the applet (regardless of
  530.      * the mouse button state). Must have been preceded by a
  531.      * call to mouseEnter().
  532.      * @see #mouseEnter
  533.      */
  534.     public void mouseExit() {
  535.     }
  536.  
  537.     /**
  538.      * Gets the focus. This is usually called in the
  539.      * mouseDown() method. A gotFocus() call will follow.
  540.      * @see Applet#gotFocus
  541.      * @see Applet#mouseDown
  542.      */
  543.     public void getFocus() {
  544.     if (! inFocusList) {
  545.         item.parent.fm.addItem(item);
  546.         inFocusList = true;
  547.     }
  548.     (item.parent.fm).grabFocus(item);
  549.     }
  550.  
  551.     /**
  552.      * Got focus. The user can now type into the applet.
  553.      * @see Applet#keyDown
  554.      */
  555.     public void gotFocus() {
  556.     }
  557.  
  558.     /**
  559.      * Lost focus.
  560.      */
  561.     public void lostFocus() {
  562.     }
  563.  
  564.     /**
  565.      * A character is typed inside the applet and it has
  566.      * the focus.
  567.      */
  568.     public void keyDown(int key) {
  569.     }
  570. }
  571.