1 /*
   2  * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.applet;
  26 
  27 import java.awt.*;
  28 import java.awt.image.ColorModel;
  29 import java.io.IOException;
  30 import java.io.ObjectInputStream;
  31 import java.net.URL;
  32 import java.net.MalformedURLException;
  33 import java.util.Hashtable;
  34 import java.util.Locale;
  35 import javax.accessibility.*;
  36 
  37 /**
  38  * An applet is a small program that is intended not to be run on
  39  * its own, but rather to be embedded inside another application.
  40  * <p>
  41  * The <code>Applet</code> class must be the superclass of any
  42  * applet that is to be embedded in a Web page or viewed by the Java
  43  * Applet Viewer. The <code>Applet</code> class provides a standard
  44  * interface between applets and their environment.
  45  *
  46  * @author      Arthur van Hoff
  47  * @author      Chris Warth
  48  * @since       1.0
  49  */
  50 public class Applet extends Panel {
  51 
  52     /**
  53      * Constructs a new Applet.
  54      * <p>
  55      * Note: Many methods in <code>java.applet.Applet</code>
  56      * may be invoked by the applet only after the applet is
  57      * fully constructed; applet should avoid calling methods
  58      * in <code>java.applet.Applet</code> in the constructor.
  59      *
  60      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  61      * returns true.
  62      * @see java.awt.GraphicsEnvironment#isHeadless
  63      * @since 1.4
  64      */
  65     public Applet() throws HeadlessException {
  66         if (GraphicsEnvironment.isHeadless()) {
  67             throw new HeadlessException();
  68         }
  69     }
  70 
  71     /**
  72      * Applets can be serialized but the following conventions MUST be followed:
  73      *
  74      * Before Serialization:
  75      * An applet must be in STOPPED state.
  76      *
  77      * After Deserialization:
  78      * The applet will be restored in STOPPED state (and most clients will
  79      * likely move it into RUNNING state).
  80      * The stub field will be restored by the reader.
  81      */
  82     private transient AppletStub stub;
  83 
  84     /* version ID for serialized form. */
  85     private static final long serialVersionUID = -5836846270535785031L;
  86 
  87     /**
  88      * Read an applet from an object input stream.
  89      * @param  s  an object input stream.
  90      * @exception HeadlessException if
  91      * <code>GraphicsEnvironment.isHeadless()</code> returns
  92      * <code>true</code>
  93      * @serial
  94      * @see java.awt.GraphicsEnvironment#isHeadless
  95      * @since 1.4
  96      */
  97     private void readObject(ObjectInputStream s)
  98         throws ClassNotFoundException, IOException, HeadlessException {
  99         if (GraphicsEnvironment.isHeadless()) {
 100             throw new HeadlessException();
 101         }
 102         s.defaultReadObject();
 103     }
 104 
 105     /**
 106      * Sets this applet's stub. This is done automatically by the system.
 107      * <p>If there is a security manager, its <code> checkPermission </code>
 108      * method is called with the
 109      * <code>AWTPermission("setAppletStub")</code>
 110      * permission if a stub has already been set.
 111      * @param   stub   the new stub.
 112      * @exception SecurityException if the caller cannot set the stub
 113      */
 114     public final void setStub(AppletStub stub) {
 115         if (this.stub != null) {
 116             SecurityManager s = System.getSecurityManager();
 117             if (s != null) {
 118                 s.checkPermission(new AWTPermission("setAppletStub"));
 119             }
 120         }
 121         this.stub = stub;
 122     }
 123 
 124     /**
 125      * Determines if this applet is active. An applet is marked active
 126      * just before its <code>start</code> method is called. It becomes
 127      * inactive just before its <code>stop</code> method is called.
 128      *
 129      * @return  <code>true</code> if the applet is active;
 130      *          <code>false</code> otherwise.
 131      * @see     java.applet.Applet#start()
 132      * @see     java.applet.Applet#stop()
 133      */
 134     public boolean isActive() {
 135         if (stub != null) {
 136             return stub.isActive();
 137         } else {        // If stub field not filled in, applet never active
 138             return false;
 139         }
 140     }
 141 
 142     /**
 143      * Gets the URL of the document in which this applet is embedded.
 144      * For example, suppose an applet is contained
 145      * within the document:
 146      * <blockquote><pre>
 147      *    http://www.oracle.com/technetwork/java/index.html
 148      * </pre></blockquote>
 149      * The document base is:
 150      * <blockquote><pre>
 151      *    http://www.oracle.com/technetwork/java/index.html
 152      * </pre></blockquote>
 153      *
 154      * @return  the {@link java.net.URL} of the document that contains this
 155      *          applet.
 156      * @see     java.applet.Applet#getCodeBase()
 157      */
 158     public URL getDocumentBase() {
 159         return stub.getDocumentBase();
 160     }
 161 
 162     /**
 163      * Gets the base URL. This is the URL of the directory which contains this applet.
 164      *
 165      * @return  the base {@link java.net.URL} of
 166      *          the directory which contains this applet.
 167      * @see     java.applet.Applet#getDocumentBase()
 168      */
 169     public URL getCodeBase() {
 170         return stub.getCodeBase();
 171     }
 172 
 173     /**
 174      * Returns the value of the named parameter in the HTML tag. For
 175      * example, if this applet is specified as
 176      * <blockquote><pre>
 177      * &lt;applet code="Clock" width=50 height=50&gt;
 178      * &lt;param name=Color value="blue"&gt;
 179      * &lt;/applet&gt;
 180      * </pre></blockquote>
 181      * <p>
 182      * then a call to <code>getParameter("Color")</code> returns the
 183      * value <code>"blue"</code>.
 184      * <p>
 185      * The <code>name</code> argument is case insensitive.
 186      *
 187      * @param   name   a parameter name.
 188      * @return  the value of the named parameter,
 189      *          or <code>null</code> if not set.
 190      */
 191      public String getParameter(String name) {
 192          return stub.getParameter(name);
 193      }
 194 
 195     /**
 196      * Determines this applet's context, which allows the applet to
 197      * query and affect the environment in which it runs.
 198      * <p>
 199      * This environment of an applet represents the document that
 200      * contains the applet.
 201      *
 202      * @return  the applet's context.
 203      */
 204     public AppletContext getAppletContext() {
 205         return stub.getAppletContext();
 206     }
 207 
 208     /**
 209      * Requests that this applet be resized.
 210      *
 211      * @param   width    the new requested width for the applet.
 212      * @param   height   the new requested height for the applet.
 213      */
 214     @SuppressWarnings("deprecation")
 215     public void resize(int width, int height) {
 216         Dimension d = size();
 217         if ((d.width != width) || (d.height != height)) {
 218             super.resize(width, height);
 219             if (stub != null) {
 220                 stub.appletResize(width, height);
 221             }
 222         }
 223     }
 224 
 225     /**
 226      * Requests that this applet be resized.
 227      *
 228      * @param   d   an object giving the new width and height.
 229      */
 230     @SuppressWarnings("deprecation")
 231     public void resize(Dimension d) {
 232         resize(d.width, d.height);
 233     }
 234 
 235     /**
 236      * Indicates if this container is a validate root.
 237      * <p>
 238      * {@code Applet} objects are the validate roots, and, therefore, they
 239      * override this method to return {@code true}.
 240      *
 241      * @return {@code true}
 242      * @since 1.7
 243      * @see java.awt.Container#isValidateRoot
 244      */
 245     @Override
 246     public boolean isValidateRoot() {
 247         return true;
 248     }
 249 
 250     /**
 251      * Requests that the argument string be displayed in the
 252      * "status window". Many browsers and applet viewers
 253      * provide such a window, where the application can inform users of
 254      * its current state.
 255      *
 256      * @param   msg   a string to display in the status window.
 257      */
 258     public void showStatus(String msg) {
 259         getAppletContext().showStatus(msg);
 260     }
 261 
 262     /**
 263      * Returns an <code>Image</code> object that can then be painted on
 264      * the screen. The <code>url</code> that is passed as an argument
 265      * must specify an absolute URL.
 266      * <p>
 267      * This method always returns immediately, whether or not the image
 268      * exists. When this applet attempts to draw the image on the screen,
 269      * the data will be loaded. The graphics primitives that draw the
 270      * image will incrementally paint on the screen.
 271      *
 272      * @param   url   an absolute URL giving the location of the image.
 273      * @return  the image at the specified URL.
 274      * @see     java.awt.Image
 275      */
 276     public Image getImage(URL url) {
 277         return getAppletContext().getImage(url);
 278     }
 279 
 280     /**
 281      * Returns an <code>Image</code> object that can then be painted on
 282      * the screen. The <code>url</code> argument must specify an absolute
 283      * URL. The <code>name</code> argument is a specifier that is
 284      * relative to the <code>url</code> argument.
 285      * <p>
 286      * This method always returns immediately, whether or not the image
 287      * exists. When this applet attempts to draw the image on the screen,
 288      * the data will be loaded. The graphics primitives that draw the
 289      * image will incrementally paint on the screen.
 290      *
 291      * @param   url    an absolute URL giving the base location of the image.
 292      * @param   name   the location of the image, relative to the
 293      *                 <code>url</code> argument.
 294      * @return  the image at the specified URL.
 295      * @see     java.awt.Image
 296      */
 297     public Image getImage(URL url, String name) {
 298         try {
 299             return getImage(new URL(url, name));
 300         } catch (MalformedURLException e) {
 301             return null;
 302         }
 303     }
 304 
 305     /**
 306      * Get an audio clip from the given URL.
 307      *
 308      * @param url points to the audio clip
 309      * @return the audio clip at the specified URL.
 310      *
 311      * @since       1.2
 312      */
 313     public static final AudioClip newAudioClip(URL url) {
 314         return new sun.applet.AppletAudioClip(url);
 315     }
 316 
 317     /**
 318      * Returns the <code>AudioClip</code> object specified by the
 319      * <code>URL</code> argument.
 320      * <p>
 321      * This method always returns immediately, whether or not the audio
 322      * clip exists. When this applet attempts to play the audio clip, the
 323      * data will be loaded.
 324      *
 325      * @param   url  an absolute URL giving the location of the audio clip.
 326      * @return  the audio clip at the specified URL.
 327      * @see     java.applet.AudioClip
 328      */
 329     public AudioClip getAudioClip(URL url) {
 330         return getAppletContext().getAudioClip(url);
 331     }
 332 
 333     /**
 334      * Returns the <code>AudioClip</code> object specified by the
 335      * <code>URL</code> and <code>name</code> arguments.
 336      * <p>
 337      * This method always returns immediately, whether or not the audio
 338      * clip exists. When this applet attempts to play the audio clip, the
 339      * data will be loaded.
 340      *
 341      * @param   url    an absolute URL giving the base location of the
 342      *                 audio clip.
 343      * @param   name   the location of the audio clip, relative to the
 344      *                 <code>url</code> argument.
 345      * @return  the audio clip at the specified URL.
 346      * @see     java.applet.AudioClip
 347      */
 348     public AudioClip getAudioClip(URL url, String name) {
 349         try {
 350             return getAudioClip(new URL(url, name));
 351         } catch (MalformedURLException e) {
 352             return null;
 353         }
 354     }
 355 
 356     /**
 357      * Returns information about this applet. An applet should override
 358      * this method to return a <code>String</code> containing information
 359      * about the author, version, and copyright of the applet.
 360      * <p>
 361      * The implementation of this method provided by the
 362      * <code>Applet</code> class returns <code>null</code>.
 363      *
 364      * @return  a string containing information about the author, version, and
 365      *          copyright of the applet.
 366      */
 367     public String getAppletInfo() {
 368         return null;
 369     }
 370 
 371     /**
 372      * Gets the locale of the applet. It allows the applet
 373      * to maintain its own locale separated from the locale
 374      * of the browser or appletviewer.
 375      *
 376      * @return  the locale of the applet; if no locale has
 377      *          been set, the default locale is returned.
 378      * @since   1.1
 379      */
 380     public Locale getLocale() {
 381       Locale locale = super.getLocale();
 382       if (locale == null) {
 383         return Locale.getDefault();
 384       }
 385       return locale;
 386     }
 387 
 388     /**
 389      * Returns information about the parameters that are understood by
 390      * this applet. An applet should override this method to return an
 391      * array of <code>Strings</code> describing these parameters.
 392      * <p>
 393      * Each element of the array should be a set of three
 394      * <code>Strings</code> containing the name, the type, and a
 395      * description. For example:
 396      * <blockquote><pre>
 397      * String pinfo[][] = {
 398      *   {"fps",    "1-10",    "frames per second"},
 399      *   {"repeat", "boolean", "repeat image loop"},
 400      *   {"imgs",   "url",     "images directory"}
 401      * };
 402      * </pre></blockquote>
 403      * <p>
 404      * The implementation of this method provided by the
 405      * <code>Applet</code> class returns <code>null</code>.
 406      *
 407      * @return  an array describing the parameters this applet looks for.
 408      */
 409     public String[][] getParameterInfo() {
 410         return null;
 411     }
 412 
 413     /**
 414      * Plays the audio clip at the specified absolute URL. Nothing
 415      * happens if the audio clip cannot be found.
 416      *
 417      * @param   url   an absolute URL giving the location of the audio clip.
 418      */
 419     public void play(URL url) {
 420         AudioClip clip = getAudioClip(url);
 421         if (clip != null) {
 422             clip.play();
 423         }
 424     }
 425 
 426     /**
 427      * Plays the audio clip given the URL and a specifier that is
 428      * relative to it. Nothing happens if the audio clip cannot be found.
 429      *
 430      * @param   url    an absolute URL giving the base location of the
 431      *                 audio clip.
 432      * @param   name   the location of the audio clip, relative to the
 433      *                 <code>url</code> argument.
 434      */
 435     public void play(URL url, String name) {
 436         AudioClip clip = getAudioClip(url, name);
 437         if (clip != null) {
 438             clip.play();
 439         }
 440     }
 441 
 442     /**
 443      * Called by the browser or applet viewer to inform
 444      * this applet that it has been loaded into the system. It is always
 445      * called before the first time that the <code>start</code> method is
 446      * called.
 447      * <p>
 448      * A subclass of <code>Applet</code> should override this method if
 449      * it has initialization to perform. For example, an applet with
 450      * threads would use the <code>init</code> method to create the
 451      * threads and the <code>destroy</code> method to kill them.
 452      * <p>
 453      * The implementation of this method provided by the
 454      * <code>Applet</code> class does nothing.
 455      *
 456      * @see     java.applet.Applet#destroy()
 457      * @see     java.applet.Applet#start()
 458      * @see     java.applet.Applet#stop()
 459      */
 460     public void init() {
 461     }
 462 
 463     /**
 464      * Called by the browser or applet viewer to inform
 465      * this applet that it should start its execution. It is called after
 466      * the <code>init</code> method and each time the applet is revisited
 467      * in a Web page.
 468      * <p>
 469      * A subclass of <code>Applet</code> should override this method if
 470      * it has any operation that it wants to perform each time the Web
 471      * page containing it is visited. For example, an applet with
 472      * animation might want to use the <code>start</code> method to
 473      * resume animation, and the <code>stop</code> method to suspend the
 474      * animation.
 475      * <p>
 476      * Note: some methods, such as <code>getLocationOnScreen</code>, can only
 477      * provide meaningful results if the applet is showing.  Because
 478      * <code>isShowing</code> returns <code>false</code> when the applet's
 479      * <code>start</code> is first called, methods requiring
 480      * <code>isShowing</code> to return <code>true</code> should be called from
 481      * a <code>ComponentListener</code>.
 482      * <p>
 483      * The implementation of this method provided by the
 484      * <code>Applet</code> class does nothing.
 485      *
 486      * @see     java.applet.Applet#destroy()
 487      * @see     java.applet.Applet#init()
 488      * @see     java.applet.Applet#stop()
 489      * @see     java.awt.Component#isShowing()
 490      * @see     java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
 491      */
 492     public void start() {
 493     }
 494 
 495     /**
 496      * Called by the browser or applet viewer to inform
 497      * this applet that it should stop its execution. It is called when
 498      * the Web page that contains this applet has been replaced by
 499      * another page, and also just before the applet is to be destroyed.
 500      * <p>
 501      * A subclass of <code>Applet</code> should override this method if
 502      * it has any operation that it wants to perform each time the Web
 503      * page containing it is no longer visible. For example, an applet
 504      * with animation might want to use the <code>start</code> method to
 505      * resume animation, and the <code>stop</code> method to suspend the
 506      * animation.
 507      * <p>
 508      * The implementation of this method provided by the
 509      * <code>Applet</code> class does nothing.
 510      *
 511      * @see     java.applet.Applet#destroy()
 512      * @see     java.applet.Applet#init()
 513      */
 514     public void stop() {
 515     }
 516 
 517     /**
 518      * Called by the browser or applet viewer to inform
 519      * this applet that it is being reclaimed and that it should destroy
 520      * any resources that it has allocated. The <code>stop</code> method
 521      * will always be called before <code>destroy</code>.
 522      * <p>
 523      * A subclass of <code>Applet</code> should override this method if
 524      * it has any operation that it wants to perform before it is
 525      * destroyed. For example, an applet with threads would use the
 526      * <code>init</code> method to create the threads and the
 527      * <code>destroy</code> method to kill them.
 528      * <p>
 529      * The implementation of this method provided by the
 530      * <code>Applet</code> class does nothing.
 531      *
 532      * @see     java.applet.Applet#init()
 533      * @see     java.applet.Applet#start()
 534      * @see     java.applet.Applet#stop()
 535      */
 536     public void destroy() {
 537     }
 538 
 539     //
 540     // Accessibility support
 541     //
 542 
 543     AccessibleContext accessibleContext = null;
 544 
 545     /**
 546      * Gets the AccessibleContext associated with this Applet.
 547      * For applets, the AccessibleContext takes the form of an
 548      * AccessibleApplet.
 549      * A new AccessibleApplet instance is created if necessary.
 550      *
 551      * @return an AccessibleApplet that serves as the
 552      *         AccessibleContext of this Applet
 553      * @since 1.3
 554      */
 555     public AccessibleContext getAccessibleContext() {
 556         if (accessibleContext == null) {
 557             accessibleContext = new AccessibleApplet();
 558         }
 559         return accessibleContext;
 560     }
 561 
 562     /**
 563      * This class implements accessibility support for the
 564      * <code>Applet</code> class.  It provides an implementation of the
 565      * Java Accessibility API appropriate to applet user-interface elements.
 566      * @since 1.3
 567      */
 568     protected class AccessibleApplet extends AccessibleAWTPanel {
 569 
 570         private static final long serialVersionUID = 8127374778187708896L;
 571 
 572         /**
 573          * Get the role of this object.
 574          *
 575          * @return an instance of AccessibleRole describing the role of the
 576          * object
 577          */
 578         public AccessibleRole getAccessibleRole() {
 579             return AccessibleRole.FRAME;
 580         }
 581 
 582         /**
 583          * Get the state of this object.
 584          *
 585          * @return an instance of AccessibleStateSet containing the current
 586          * state set of the object
 587          * @see AccessibleState
 588          */
 589         public AccessibleStateSet getAccessibleStateSet() {
 590             AccessibleStateSet states = super.getAccessibleStateSet();
 591             states.add(AccessibleState.ACTIVE);
 592             return states;
 593         }
 594 
 595     }
 596 }