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