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