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