AppletPanel.java revision 215
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * This code is free software; you can redistribute it and/or modify it
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * under the terms of the GNU General Public License version 2 only, as
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * published by the Free Software Foundation. Sun designates this
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * particular file as subject to the "Classpath" exception as provided
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * by Sun in the LICENSE file that accompanied this code.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * This code is distributed in the hope that it will be useful, but WITHOUT
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * version 2 for more details (a copy is included in the LICENSE file that
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * accompanied this code).
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You should have received a copy of the GNU General Public License version
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * 2 along with this work; if not, write to the Free Software Foundation,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CA 95054 USA or visit www.sun.com if you need additional information or
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * have any questions.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowepackage sun.applet;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.applet.*;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.awt.*;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.awt.event.*;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.awt.image.ColorModel;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.awt.image.MemoryImageSource;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.io.*;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.lang.ref.WeakReference;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.lang.reflect.InvocationTargetException;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.lang.reflect.Method;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.net.InetAddress;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.net.JarURLConnection;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.net.MalformedURLException;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.net.SocketPermission;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.net.URL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.net.UnknownHostException;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.security.*;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.util.*;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.util.Collections;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.util.Locale;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport java.util.WeakHashMap;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport javax.swing.SwingUtilities;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport sun.awt.AppContext;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport sun.awt.EmbeddedFrame;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport sun.awt.SunToolkit;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport sun.misc.MessageUtils;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport sun.misc.PerformanceLogger;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport sun.misc.Queue;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweimport sun.security.util.SecurityConstants;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Applet panel class. The panel manages and manipulates the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * applet as it is being loaded. It forks a separate thread in a new
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * thread group to call the applet's init(), start(), stop(), and
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * destroy() methods.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * @author Arthur van Hoff
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowepublic
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweabstract class AppletPanel extends Panel implements AppletStub, Runnable {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The applet (if loaded).
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Applet applet;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Applet will allow initialization. Should be
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * set to false if loading a serialized applet
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * that was pickled in the init=true state.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected boolean doInit = true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The classloader for the applet.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AppletClassLoader loader;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* applet event ids */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_DISPOSE = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_LOAD = 1;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_INIT = 2;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_START = 3;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_STOP = 4;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_DESTROY = 5;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_QUIT = 6;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_ERROR = 7;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* send to the parent to force relayout */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_RESIZE = 51234;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* sent to a (distant) parent to indicate that the applet is being
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * loaded or as completed loading
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_LOADING = 51235;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public final static int APPLET_LOADING_COMPLETED = 51236;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The current status. One of:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_DISPOSE,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_LOAD,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_INIT,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_START,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_STOP,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_DESTROY,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_ERROR.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected int status;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The thread for the applet.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Thread handler;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The initial applet size.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Dimension defaultAppletSize = new Dimension(10, 10);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The current applet size.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Dimension currentAppletSize = new Dimension(10, 10);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe MessageUtils mu = new MessageUtils();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The thread to use during applet loading
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Thread loaderThread = null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Flag to indicate that a loading has been cancelled
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe boolean loadAbortRequest = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* abstract classes */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe abstract protected String getCode();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe abstract protected String getJarFiles();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe abstract protected String getSerializedObject();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe abstract public int getWidth();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe abstract public int getHeight();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe abstract public boolean hasInitialFocus();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe private static int threadGroupNumber = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected void setupAppletAppContext() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // do nothing
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Creates a thread to run the applet. This method is called
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * each time an applet is loaded and reloaded.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe synchronized void createAppletThread() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Create a thread group for the applet, and start a new
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // thread to load the applet.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe String nm = "applet-" + getCode();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader.grab(); // Keep this puppy around!
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // 4668479: Option to turn off codebase lookup in AppletClassLoader
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // during resource requests. [stanley.ho]
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe String param = getParameter("codebase_lookup");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (param != null && param.equals("false"))
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader.setCodebaseLookup(false);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe else
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader.setCodebaseLookup(true);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ThreadGroup appletGroup = loader.getThreadGroup();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe handler = new Thread(appletGroup, this, "thread " + nm);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // set the context class loader for this thread
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AccessController.doPrivileged(new PrivilegedAction() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public Object run() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe handler.setContextClassLoader(loader);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe });
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe handler.start();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe void joinAppletThread() throws InterruptedException {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (handler != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe handler.join();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe handler = null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe void release() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (loader != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader.release();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader = null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Construct an applet viewer and start the applet.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void init() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Get the width (if any)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe defaultAppletSize.width = getWidth();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe currentAppletSize.width = defaultAppletSize.width;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Get the height (if any)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe defaultAppletSize.height = getHeight();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe currentAppletSize.height = defaultAppletSize.height;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (NumberFormatException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Turn on the error flag and let TagAppletPanel
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // do the right thing.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("badattribute.exception");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletLog("badattribute.exception");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletException(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe setLayout(new BorderLayout());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe createAppletThread();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Minimum size
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public Dimension minimumSize() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return new Dimension(defaultAppletSize.width,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe defaultAppletSize.height);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Preferred size
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public Dimension preferredSize() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return new Dimension(currentAppletSize.width,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe currentAppletSize.height);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe private AppletListener listeners;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * AppletEvent Queue
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe private Queue queue = null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe synchronized public void addAppletListener(AppletListener l) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe listeners = AppletEventMulticaster.add(listeners, l);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe synchronized public void removeAppletListener(AppletListener l) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe listeners = AppletEventMulticaster.remove(listeners, l);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Dispatch event to the listeners..
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void dispatchAppletEvent(int id, Object argument) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe //System.out.println("SEND= " + id);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (listeners != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AppletEvent evt = new AppletEvent(this, id, argument);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe listeners.appletStateChanged(evt);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Send an event. Queue it for execution by the handler thread.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void sendEvent(int id) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe synchronized(this) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (queue == null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe //System.out.println("SEND0= " + id);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe queue = new Queue();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Integer eventId = Integer.valueOf(id);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe queue.enqueue(eventId);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe notifyAll();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (id == APPLET_QUIT) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe joinAppletThread(); // Let the applet event handler exit
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (InterruptedException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // AppletClassLoader.release() must be called by a Thread
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // not within the applet's ThreadGroup
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (loader == null)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe release();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Get an event from the queue.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe synchronized AppletEvent getNextEvent() throws InterruptedException {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while (queue == null || queue.isEmpty()) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wait();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Integer eventId = (Integer)queue.dequeue();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return new AppletEvent(this, eventId.intValue(), null);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe boolean emptyEventQueue() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((queue == null) || (queue.isEmpty()))
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe else
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * This kludge is specific to get over AccessControlException thrown during
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Applet.stop() or destroy() when static thread is suspended. Set a flag
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * in AppletClassLoader to indicate that an
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * AccessControlException for RuntimePermission "modifyThread" or
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * "modifyThreadGroup" had occurred.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe private void setExceptionStatus(AccessControlException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Permission p = e.getPermission();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (p instanceof RuntimePermission) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (p.getName().startsWith("modifyThread")) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (loader == null)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader.setExceptionStatus();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Execute applet events.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Here is the state transition diagram
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Note: (XXX) is the action
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_XXX is the state
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * (applet code loaded) --> APPLET_LOAD -- (applet init called)--> APPLET_INIT -- (
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * applet start called) --> APPLET_START -- (applet stop called) -->APPLET_STOP --(applet
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * destroyed called) --> APPLET_DESTROY -->(applet gets disposed) -->
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_DISPOSE -->....
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * In the legacy lifecycle model. The applet gets loaded, inited and started. So it stays
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * in the APPLET_START state unless the applet goes away(refresh page or leave the page).
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * So the applet stop method called and the applet enters APPLET_STOP state. Then if the applet
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * is revisited, it will call applet start method and enter the APPLET_START state and stay there.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * In the modern lifecycle model. When the applet first time visited, it is same as legacy lifecycle
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * model. However, when the applet page goes away. It calls applet stop method and enters APPLET_STOP
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * state and then applet destroyed method gets called and enters APPLET_DESTROY state.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * This code is also called by AppletViewer. In AppletViewer "Restart" menu, the applet is jump from
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_STOP to APPLET_DESTROY and to APPLET_INIT .
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Also, the applet can jump from APPLET_INIT state to APPLET_DESTROY (in Netscape/Mozilla case).
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Same as APPLET_LOAD to
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * APPLET_DISPOSE since all of this are triggered by browser.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void run() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Thread curThread = Thread.currentThread();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (curThread == loaderThread) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // if we are in the loader thread, cause
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // loading to occur. We may exit this with
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // status being APPLET_DISPOSE, APPLET_ERROR,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // or APPLET_LOAD
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe runLoader();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe boolean disposed = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while (!disposed && !curThread.isInterrupted()) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AppletEvent evt;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe evt = getNextEvent();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (InterruptedException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("bail");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe //showAppletStatus("EVENT = " + evt.getID());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe switch (evt.getID()) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case APPLET_LOAD:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (!okToLoad()) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // This complexity allows loading of applets to be
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // interruptable. The actual thread loading runs
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // in a separate thread, so it can be interrupted
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // without harming the applet thread.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // So that we don't have to worry about
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // concurrency issues, the main applet thread waits
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // until the loader thread terminates.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // (one way or another).
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (loaderThread == null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // REMIND: do we want a name?
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe //System.out.println("------------------- loading applet");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe setLoaderThread(new Thread(this));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loaderThread.start();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // we get to go to sleep while this runs
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loaderThread.join();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe setLoaderThread(null);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // REMIND: issue an error -- this case should never
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // occur.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case APPLET_INIT:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // AppletViewer "Restart" will jump from destroy method to
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // init, that is why we need to check status w/ APPLET_DESTROY
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (status != APPLET_LOAD && status != APPLET_DESTROY) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("notloaded");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet.resize(defaultAppletSize);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (doInit) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (PerformanceLogger.loggingEnabled()) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe PerformanceLogger.setTime("Applet Init");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe PerformanceLogger.outputLog();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet.init();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe //Need the default(fallback) font to be created in this AppContext
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Font f = getFont();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (f == null ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "dialog".equals(f.getFamily().toLowerCase(Locale.ENGLISH)) &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe f.getSize() == 12 && f.getStyle() == Font.PLAIN) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe setFont(new Font(Font.DIALOG, Font.PLAIN, 12));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe doInit = true; // allow restarts
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Validate the applet in event dispatch thread
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // to avoid deadlock.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe final AppletPanel p = this;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe SwingUtilities.invokeAndWait(new Runnable() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void run() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe p.validate();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe });
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe catch(InterruptedException ie) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe catch(InvocationTargetException ite) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_INIT;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("inited");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case APPLET_START:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (status != APPLET_INIT && status != APPLET_STOP) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("notinited");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet.resize(currentAppletSize);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet.start();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Validate and show the applet in event dispatch thread
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // to avoid deadlock.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe final AppletPanel p = this;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe final Applet a = applet;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe SwingUtilities.invokeAndWait(new Runnable() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void run() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe p.validate();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe a.setVisible(true);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Fix for BugTraq ID 4041703.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Set the default focus for an applet.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (hasInitialFocus())
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe setDefaultFocus();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe });
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe catch(InterruptedException ie) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe catch(InvocationTargetException ite) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_START;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("started");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case APPLET_STOP:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (status != APPLET_START) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("notstarted");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_STOP;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Hide the applet in event dispatch thread
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // to avoid deadlock.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe final Applet a = applet;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe SwingUtilities.invokeAndWait(new Runnable() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void run()
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe a.setVisible(false);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe });
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe catch(InterruptedException ie) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe catch(InvocationTargetException ite) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // During Applet.stop(), any AccessControlException on an involved Class remains in
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // reused, the same exception will occur during class loading. Set the AppletClassLoader's
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // exceptionStatusSet flag to allow recognition of what had happened
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // when reusing AppletClassLoader object.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet.stop();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (java.security.AccessControlException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe setExceptionStatus(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // rethrow exception to be handled as it normally would be.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe throw e;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("stopped");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case APPLET_DESTROY:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (status != APPLET_STOP && status != APPLET_INIT) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("notstopped");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_DESTROY;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // During Applet.destroy(), any AccessControlException on an involved Class remains in
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // the "memory" of the AppletClassLoader. If the same instance of the ClassLoader is
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // reused, the same exception will occur during class loading. Set the AppletClassLoader's
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // exceptionStatusSet flag to allow recognition of what had happened
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // when reusing AppletClassLoader object.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet.destroy();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (java.security.AccessControlException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe setExceptionStatus(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // rethrow exception to be handled as it normally would be.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe throw e;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("destroyed");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case APPLET_DISPOSE:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (status != APPLET_DESTROY && status != APPLET_LOAD) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("notdestroyed");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_DISPOSE;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe final Applet a = applet;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe EventQueue.invokeAndWait(new Runnable()
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void run()
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe remove(a);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe });
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe catch(InterruptedException ie)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe catch(InvocationTargetException ite)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet = null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("disposed");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe disposed = true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case APPLET_QUIT:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (Exception e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (e.getMessage() != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("exception2", e.getClass().getName(),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe e.getMessage());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("exception", e.getClass().getName());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletException(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (ThreadDeath e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("death");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (Error e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (e.getMessage() != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("error2", e.getClass().getName(),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe e.getMessage());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("error", e.getClass().getName());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletException(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe clearLoadAbortRequest();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Gets most recent focus owner component associated with the given window.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * It does that without calling Window.getMostRecentFocusOwner since it
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * provides its own logic contradicting with setDefautlFocus. Instead, it
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * calls KeyboardFocusManager directly.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe private Component getMostRecentFocusOwnerForWindow(Window w) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Method meth = (Method)AccessController.doPrivileged(new PrivilegedAction() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public Object run() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Method meth = null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe meth = KeyboardFocusManager.class.getDeclaredMethod("getMostRecentFocusOwner", new Class[] {Window.class});
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe meth.setAccessible(true);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (Exception e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Must never happen
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe e.printStackTrace();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return meth;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe });
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (meth != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Meth refers static method
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return (Component)meth.invoke(null, new Object[] {w});
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (Exception e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Must never happen
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe e.printStackTrace();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Will get here if exception was thrown or meth is null
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return w.getMostRecentFocusOwner();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Fix for BugTraq ID 4041703.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Set the focus to a reasonable default for an Applet.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe private void setDefaultFocus() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Component toFocus = null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Container parent = getParent();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(parent != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (parent instanceof Window) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe toFocus = getMostRecentFocusOwnerForWindow((Window)parent);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (toFocus == parent || toFocus == null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe toFocus = parent.getFocusTraversalPolicy().
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe getInitialComponent((Window)parent);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else if (parent.isFocusCycleRoot()) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe toFocus = parent.getFocusTraversalPolicy().
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe getDefaultComponent(parent);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (toFocus != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (parent instanceof EmbeddedFrame) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ((EmbeddedFrame)parent).synthesizeWindowActivation(true);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // EmbeddedFrame might have focus before the applet was added.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Thus after its activation the most recent focus owner will be
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // restored. We need the applet's initial focusabled component to
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // be focused here.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe toFocus.requestFocusInWindow();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Load the applet into memory.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Runs in a seperate (and interruptible) thread from the rest of the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * applet event processing so that it can be gracefully interrupted from
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * things like HotJava.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe private void runLoader() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (status != APPLET_DISPOSE) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("notdisposed");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe dispatchAppletEvent(APPLET_LOADING, null);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // REMIND -- might be cool to visually indicate loading here --
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // maybe do animation?
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_LOAD;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Create a class loader
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Load the archives if present.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // REMIND - this probably should be done in a separate thread,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // or at least the additional archives (epll).
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe String code = getCode();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // setup applet AppContext
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // this must be called before loadJarFiles
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe setupAppletAppContext();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loadJarFiles(loader);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet = createApplet(loader);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (ClassNotFoundException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("notfound", code);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletLog("notfound", code);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletException(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (InstantiationException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("nocreate", code);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletLog("nocreate", code);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletException(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (IllegalAccessException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("noconstruct", code);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletLog("noconstruct", code);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletException(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // sbb -- I added a return here
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (Exception e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("exception", e.getMessage());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletException(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (ThreadDeath e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("death");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (Error e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("error", e.getMessage());
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletException(e);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } finally {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // notify that loading is no longer going on
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe dispatchAppletEvent(APPLET_LOADING_COMPLETED, null);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Fixed #4508194: NullPointerException thrown during
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // quick page switch
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe //
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (applet != null)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Stick it in the frame
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet.setStub(this);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet.hide();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe add("Center", applet);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("loaded");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe validate();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected Applet createApplet(final AppletClassLoader loader) throws ClassNotFoundException,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe IllegalAccessException, IOException, InstantiationException, InterruptedException {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe final String serName = getSerializedObject();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe String code = getCode();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (code != null && serName != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe System.err.println(amh.getMessage("runloader.err"));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe// return null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe throw new InstantiationException("Either \"code\" or \"object\" should be specified, but not both.");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (code == null && serName == null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe String msg = "nocode";
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_ERROR;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus(msg);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletLog(msg);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe repaint();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (code != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet = (Applet)loader.loadCode(code).newInstance();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe doInit = true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // serName is not null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe InputStream is = (InputStream)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe java.security.AccessController.doPrivileged(
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe new java.security.PrivilegedAction() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public Object run() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return loader.getResourceAsStream(serName);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe });
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ObjectInputStream ois =
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe new AppletObjectInputStream(is, loader);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Object serObject = ois.readObject();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet = (Applet) serObject;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe doInit = false; // skip over the first init
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Determine the JDK level that the applet targets.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // This is critical for enabling certain backward
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // compatibility switch if an applet is a JDK 1.1
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // applet. [stanley.ho]
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe findAppletJDKLevel(applet);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (Thread.interrupted()) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe status = APPLET_DISPOSE; // APPLET_ERROR?
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe applet = null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // REMIND: This may not be exactly the right thing: the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // status is set by the stop button and not necessarily
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // here.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe showAppletStatus("death");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } finally {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Thread.currentThread().interrupt(); // resignal interrupt
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return applet;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected void loadJarFiles(AppletClassLoader loader) throws IOException,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe InterruptedException {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // Load the archives if present.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // REMIND - this probably should be done in a separate thread,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // or at least the additional archives (epll).
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe String jarFiles = getJarFiles();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (jarFiles != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe StringTokenizer st = new StringTokenizer(jarFiles, ",", false);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while(st.hasMoreTokens()) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe String tok = st.nextToken().trim();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe try {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loader.addJar(tok);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } catch (IllegalArgumentException e) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // bad archive name
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe continue;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Request that the loading of the applet be stopped.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected synchronized void stopLoading() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe // REMIND: fill in the body
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (loaderThread != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe //System.out.println("Interrupting applet loader thread: " + loaderThread);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loaderThread.interrupt();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe setLoadAbortRequest();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected synchronized boolean okToLoad() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return !loadAbortRequest;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected synchronized void clearLoadAbortRequest() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loadAbortRequest = false;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected synchronized void setLoadAbortRequest() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe loadAbortRequest = true;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe private synchronized void setLoaderThread(Thread loaderThread) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe this.loaderThread = loaderThread;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Return true when the applet has been started.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public boolean isActive() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return status == APPLET_START;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe private EventQueue appEvtQ = null;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Is called when the applet wants to be resized.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void appletResize(int width, int height) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe currentAppletSize.width = width;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe currentAppletSize.height = height;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe final Dimension currentSize = new Dimension(currentAppletSize.width,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe currentAppletSize.height);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(loader != null) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AppContext appCtxt = loader.getAppContext();
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(appCtxt != null)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe appEvtQ = (java.awt.EventQueue)appCtxt.get(AppContext.EVENT_QUEUE_KEY);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe final AppletPanel ap = this;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (appEvtQ != null){
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe appEvtQ.postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe new Runnable(){
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void run(){
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(ap != null)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ap.dispatchAppletEvent(APPLET_RESIZE, currentSize);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public void setBounds(int x, int y, int width, int height) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe super.setBounds(x, y, width, height);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe currentAppletSize.width = width;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe currentAppletSize.height = height;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe public Applet getApplet() {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return applet;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /**
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Status line. Called by the AppletPanel to provide
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * feedback on the Applet's state.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected void showAppletStatus(String status) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe getAppletContext().showStatus(amh.getMessage(status));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe protected void showAppletStatus(String status, Object arg) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe getAppletContext().showStatus(amh.getMessage(status, arg));
}
protected void showAppletStatus(String status, Object arg1, Object arg2) {
getAppletContext().showStatus(amh.getMessage(status, arg1, arg2));
}
/**
* Called by the AppletPanel to print to the log.
*/
protected void showAppletLog(String msg) {
System.out.println(amh.getMessage(msg));
}
protected void showAppletLog(String msg, Object arg) {
System.out.println(amh.getMessage(msg, arg));
}
/**
* Called by the AppletPanel to provide
* feedback when an exception has happened.
*/
protected void showAppletException(Throwable t) {
t.printStackTrace();
repaint();
}
/**
* Get caching key for classloader cache
*/
public String getClassLoaderCacheKey()
{
/**
* Fixed #4501142: Classlaoder sharing policy doesn't
* take "archive" into account. This will be overridden
* by Java Plug-in. [stanleyh]
*/
return getCodeBase().toString();
}
/**
* The class loaders
*/
private static HashMap classloaders = new HashMap();
/**
* Flush a class loader.
*/
public static synchronized void flushClassLoader(String key) {
classloaders.remove(key);
}
/**
* Flush all class loaders.
*/
public static synchronized void flushClassLoaders() {
classloaders = new HashMap();
}
/**
* This method actually creates an AppletClassLoader.
*
* It can be override by subclasses (such as the Plug-in)
* to provide different classloaders.
*/
protected AppletClassLoader createClassLoader(final URL codebase) {
return new AppletClassLoader(codebase);
}
/**
* Get a class loader. Create in a restricted context
*/
synchronized AppletClassLoader getClassLoader(final URL codebase, final String key) {
AppletClassLoader c = (AppletClassLoader)classloaders.get(key);
if (c == null) {
AccessControlContext acc =
getAccessControlContext(codebase);
c = (AppletClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
AppletClassLoader ac = createClassLoader(codebase);
/* Should the creation of the classloader be
* within the class synchronized block? Since
* this class is used by the plugin, take care
* to avoid deadlocks, or specialize
* AppletPanel within the plugin. It may take
* an arbitrary amount of time to create a
* class loader (involving getting Jar files
* etc.) and may block unrelated applets from
* finishing createAppletThread (due to the
* class synchronization). If
* createAppletThread does not finish quickly,
* the applet cannot process other messages,
* particularly messages such as destroy
* (which timeout when called from the browser).
*/
synchronized (getClass()) {
AppletClassLoader res =
(AppletClassLoader)classloaders.get(key);
if (res == null) {
classloaders.put(key, ac);
return ac;
} else {
return res;
}
}
}
},acc);
}
return c;
}
/**
* get the context for the AppletClassLoader we are creating.
* the context is granted permission to create the class loader,
* connnect to the codebase, and whatever else the policy grants
* to all codebases.
*/
private AccessControlContext getAccessControlContext(final URL codebase) {
PermissionCollection perms = (PermissionCollection)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
Policy p = java.security.Policy.getPolicy();
if (p != null) {
return p.getPermissions(new CodeSource(null,
(java.security.cert.Certificate[]) null));
} else {
return null;
}
}
});
if (perms == null)
perms = new Permissions();
//XXX: this is needed to be able to create the classloader itself!
perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
Permission p;
java.net.URLConnection urlConnection = null;
try {
urlConnection = codebase.openConnection();
p = urlConnection.getPermission();
} catch (java.io.IOException ioe) {
p = null;
}
if (p != null)
perms.add(p);
if (p instanceof FilePermission) {
String path = p.getName();
int endIndex = path.lastIndexOf(File.separatorChar);
if (endIndex != -1) {
path = path.substring(0, endIndex+1);
if (path.endsWith(File.separator)) {
path += "-";
}
perms.add(new FilePermission(path,
SecurityConstants.FILE_READ_ACTION));
}
} else {
URL locUrl = codebase;
if (urlConnection instanceof JarURLConnection) {
locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
}
String host = locUrl.getHost();
if (host != null && (host.length() > 0))
perms.add(new SocketPermission(host,
SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION));
}
ProtectionDomain domain =
new ProtectionDomain(new CodeSource(codebase,
(java.security.cert.Certificate[]) null), perms);
AccessControlContext acc =
new AccessControlContext(new ProtectionDomain[] { domain });
return acc;
}
public Thread getAppletHandlerThread() {
return handler;
}
public int getAppletWidth() {
return currentAppletSize.width;
}
public int getAppletHeight() {
return currentAppletSize.height;
}
public static void changeFrameAppContext(Frame frame, AppContext newAppContext)
{
// Fixed #4754451: Applet can have methods running on main
// thread event queue.
//
// The cause of this bug is that the frame of the applet
// is created in main thread group. Thus, when certain
// AWT/Swing events are generated, the events will be
// dispatched through the wrong event dispatch thread.
//
// To fix this, we rearrange the AppContext with the frame,
// so the proper event queue will be looked up.
//
// Swing also maintains a Frame list for the AppContext,
// so we will have to rearrange it as well.
// Check if frame's AppContext has already been set properly
AppContext oldAppContext = SunToolkit.targetToAppContext(frame);
if (oldAppContext == newAppContext)
return;
// Synchronization on Window.class is needed for locking the
// critical section of the window list in AppContext.
synchronized (Window.class)
{
WeakReference weakRef = null;
// Remove frame from the Window list in wrong AppContext
{
// Lookup current frame's AppContext
Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)oldAppContext.get(Window.class);
if (windowList != null) {
for (WeakReference ref : windowList) {
if (ref.get() == frame) {
weakRef = ref;
break;
}
}
// Remove frame from wrong AppContext
if (weakRef != null)
windowList.remove(weakRef);
}
}
// Put the frame into the applet's AppContext map
SunToolkit.insertTargetMapping(frame, newAppContext);
// Insert frame into the Window list in the applet's AppContext map
{
Vector<WeakReference<Window>> windowList = (Vector)newAppContext.get(Window.class);
if (windowList == null) {
windowList = new Vector<WeakReference<Window>>();
newAppContext.put(Window.class, windowList);
}
// use the same weakRef here as it is used elsewhere
windowList.add(weakRef);
}
}
}
// Flag to indicate if applet is targeted for JDK 1.1.
private boolean jdk11Applet = false;
// Flag to indicate if applet is targeted for JDK 1.2.
private boolean jdk12Applet = false;
/**
* Determine JDK level of an applet.
*/
private void findAppletJDKLevel(Applet applet)
{
// To determine the JDK level of an applet, the
// most reliable way is to check the major version
// of the applet class file.
// synchronized on applet class object, so calling from
// different instances of the same applet will be
// serialized.
Class appletClass = applet.getClass();
synchronized(appletClass) {
// Determine if the JDK level of an applet has been
// checked before.
Boolean jdk11Target = (Boolean) loader.isJDK11Target(appletClass);
Boolean jdk12Target = (Boolean) loader.isJDK12Target(appletClass);
// if applet JDK level has been checked before, retrieve
// value and return.
if (jdk11Target != null || jdk12Target != null) {
jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue();
jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue();
return;
}
String name = appletClass.getName();
// first convert any '.' to '/'
name = name.replace('.', '/');
// append .class
final String resourceName = name + ".class";
InputStream is = null;
byte[] classHeader = new byte[8];
try {
is = (InputStream) java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
return loader.getResourceAsStream(resourceName);
}
});
// Read the first 8 bytes of the class file
int byteRead = is.read(classHeader, 0, 8);
is.close();
// return if the header is not read in entirely
// for some reasons.
if (byteRead != 8)
return;
}
catch (IOException e) {
return;
}
// Check major version in class file header
int major_version = readShort(classHeader, 6);
// Major version in class file is as follows:
// 45 - JDK 1.1
// 46 - JDK 1.2
// 47 - JDK 1.3
// 48 - JDK 1.4
// 49 - JDK 1.5
if (major_version < 46)
jdk11Applet = true;
else if (major_version == 46)
jdk12Applet = true;
// Store applet JDK level in AppContext for later lookup,
// e.g. page switch.
loader.setJDK11Target(appletClass, jdk11Applet);
loader.setJDK12Target(appletClass, jdk12Applet);
}
}
/**
* Return true if applet is targeted to JDK 1.1.
*/
protected boolean isJDK11Applet() {
return jdk11Applet;
}
/**
* Return true if applet is targeted to JDK1.2.
*/
protected boolean isJDK12Applet() {
return jdk12Applet;
}
/**
* Read short from byte array.
*/
private int readShort(byte[] b, int off) {
int hi = readByte(b[off]);
int lo = readByte(b[off + 1]);
return (hi << 8) | lo;
}
private int readByte(byte b) {
return ((int)b) & 0xFF;
}
private static AppletMessageHandler amh = new AppletMessageHandler("appletpanel");
}