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