The Next Generation Java Plugin is available with Java 6_10 and later. We strongly suggest that you use the plugin rather than the applet launcher. It resolves many problems people have encountered when using the applet launcher, and it enables much more flexible control of the applet's run-time environment. Unfortunately, as of January 2009 the plugin is not yet supported on Apple OS X.
As for the World Wind Java project in general, please check the following points :
JOGL applet setup (without World Wind) can be tested with this sample Gears 3D JOGL animation applet:
https://jogl-demos.dev.java.net/applettest.html.
It's a good idea to perform this test prior to deploying the World Wind applet because it will identify any
problems the computer has using JOGL alone.
To deploy a WWJ applet you need a web page with the proper html declarations, the World Wind Java archive worldwind.jar, and possibly your special implementation of one of the applet templates in its own archive, eg. myapplet.jar. When using the Next Generation Plugin, you also need a .jnlp file.
myapplet.html Web page that loads the applet myapplet.jnlp Used with the Next Generation Plugin myapplet.jar Optional applet class in its own archive worldwind.jar World Wind Java SDK, including applet templates
Using either the Next Generation Plugin or the JNLPAppletLauncher all other needed components can be retrieved from external servers: the launcher itself applet-laucher.jar (not needed if you're using the Next Generation Plugin), and the JOGL librairies jogl.jar and gluegen-rt.jar. The appropriate binaries will be downloaded and cached according to the client platform by the launcher.
To compile and deploy a WW applet, follow these steps:
The World Wind Java SDK comes with a build.xml file containing various ant targets to compile, release and zip different parts of the SDK. The applet.release target will do all the work and place all needed files in the applet.release folder along with example html pages.
To use a custom World Wind configuration file in your applet, place within a static block of your applet code to set the Java property that indicates the configuration file's location and name. The code must run before any World Wind method or constructor is invoked. The property is gov.nasa.worldwind.config.file (see code sample below). The path must be relative to the applet's classpath, and the configuration file must be included in the applet's signed jar file. World Wind opens the file via java.lang.Class.getResourceAsStream().
Launching an applet with the Next Generation Plugin requires a .jnlp file. Here's the HTML to use for the WWJApplet example:
<applet code="org.jdesktop.applet.util.JNLPAppletLauncher" width=600 height=400 archive="http://download.java.net/media/applet-launcher/applet-launcher.jar, http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jar, http://download.java.net/media/gluegen/webstart/gluegen-rt.jar, http://my.web.server.com/WWJApplet/worldwind.jar"> http://my.web.server.com/WWJApplet/myapplet.jar"> <param name="jnlp_href" value="WWJApplet.jnlp"> <!-- Picked up by new plugin --> <param name="codebase_lookup" value="false"> <param name="subapplet.classname" value="gov.nasa.worldwind.examples.applet.WWJApplet"> <param name="subapplet.displayname" value="World Wind Applet"> <param name="noddraw.check" value="true"> <param name="progressbar" value="true"> <param name="jnlpNumExtensions" value="1"> <param name="jnlpExtension1" value="http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp"> </applet>
The corresponding WWJApplet.jnlp file:
<?xml version="1.0" encoding="UTF-8"?> <jnlp href="WWJApplet.jnlp"> <information> <title>World Wind Java Applet Demo</title> <vendor>NASA</vendor> <homepage href="http://worldwind.arc.nasa.gov"/> <description>World Wind Java Applet Demo</description> <description kind="short">World Wind Java Applet Demo</description> <offline-allowed/> </information> <security> <all-permissions/> </security> <resources os="Windows"> <property name="sun.java2d.noddraw" value="true"/> </resources> <resources> <j2se href="http://java.sun.com/products/autodl/j2se" version="1.5+" initial-heap-size="512m" max-heap-size="512m"/> <property name="sun.java2d.noddraw" value="true"/> <jar href="WWJApplet.jar" main="true"/> <jar href="worldwind.jar"/> <extension name="jogl" href="http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp"/> </resources> <!-- Width and heigth are overwritten by the surrounding web page --> <applet-desc name="WWJ Applet" main-class="gov.nasa.worldwind.examples.applet.WWJApplet" width="800" height="600"> <param name="separate_jvm" value="true" /> </applet-desc> </jnlp>
The Next Generation Plugin allows considerable flexibility in defining the applet context. For instance, a minimal JRE version can be specified along with initial heap memory size (Java 5 and 512M in the above example). A parameter can also direct the plugin to use a different JVM for each applet instance (param separate_jvm< above). World Wind applets should always set this parameter and set its value to true.
As of January 2009 the Next Generation Plugin works with Internet Explorer 6 and 7 on Windows XP or Vista,
Firefox 3 on Windows, Solaris and Linux. You can read the new plugin release notes at
Release Notes for the Next Generation Java Plug-In Technology.
Current Java Download: Download Java
Below is the HTML code necessary to run the sample WWJApplet from the SDK applet package. Note that all achives are referenced with absolute urls to Sun's servers except the worldwind.jar that is located on another server - probably with this web page, but it could be anywhere.
"Note that this example does not specify a codebase, instead specifying all of its archive tag elements with absolute URLs (split here for readability; in a real applet tag they must be all on one line). Note also the use of the noddraw.check parameter to disable the use of DirectDraw since using JOGL implies the use of OpenGL."
<applet code="org.jdesktop.applet.util.JNLPAppletLauncher" width=600 height=400 archive="http://download.java.net/media/applet-launcher/applet-launcher.jar, http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jar, http://download.java.net/media/gluegen/webstart/gluegen-rt.jar, http://my.web.server.com/WWJApplet/worldwind.jar"> <param name="codebase_lookup" value="false"> <param name="subapplet.classname" value="gov.nasa.worldwind.examples.applet.WWJApplet"> <param name="subapplet.displayname" value="World Wind Applet"> <param name="noddraw.check" value="true"> <param name="progressbar" value="true"> <param name="jnlpNumExtensions" value="1"> <param name="jnlpExtension1" value="http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jnlp"> </applet>
If the applet code is in a separate archive, place a reference to that archive in the archive attribute of the applet, and specify the proper path in the subapplet.classname parameter:
<applet code="org.jdesktop.applet.util.JNLPAppletLauncher" width=600 height=400 archive="http://download.java.net/media/applet-launcher/applet-launcher.jar, http://download.java.net/media/jogl/builds/archive/jsr-231-webstart-current/jogl.jar, http://download.java.net/media/gluegen/webstart/gluegen-rt.jar, http://my.web.server.com/WWJApplet/worldwind.jar, http://my.web.server.com/WWJApplet/myapplet.jar"> <param name="codebase_lookup" value="false"> <param name="subapplet.classname" value="domain.your.path.myApplet"> ... </applet>
Ref : https://applet-launcher.dev.java.net/
import gov.nasa.worldwind.examples.StatusBar; import gov.nasa.worldwind.*; import gov.nasa.worldwind.geom.*; import gov.nasa.worldwind.layers.*; import gov.nasa.worldwind.awt.*; import javax.swing.*; import java.awt.*; public class WWJApplet extends JApplet { private WorldWindowGLCanvas wwd; private StatusBar statusBar; public WWJApplet() { } public void init() { try { // Create World Window GL Canvas this.wwd = new WorldWindowGLCanvas(); this.getContentPane().add(this.wwd, BorderLayout.CENTER); // Create the default model as described in the current worldwind properties. Model m = (Model) WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME); this.wwd.setModel(m); // Add the status bar this.statusBar = new StatusBar(); this.getContentPane().add(statusBar, BorderLayout.PAGE_END); // Forward events to the status bar to provide the cursor position info. this.statusBar.setEventSource(this.wwd); } catch (Throwable e) { e.printStackTrace(); } } public void stop() { // Shutdown World Wind WorldWind.shutDown(); } }
If the applet uses a custom World Wind configuration file, the following would be added to the WWJApplet class above:
static { System.setProperty("gov.nasa.worldwind.config.file", "config/myWorldWindConfiguration.properties"); }
This property must be set prior to any other World Wind method invocation or object construction. In this example, the properties file would be contained at the above path within the applet's jar file.
When a wwj applet is started the first time with an empty cache, the globe will not show until the level zero tiles of blue marble are downloaded. To avoid this delay and an initial display of a blank globe, add in the layer list, before 'blue marble' a full sphere SurfaceImage of a low resolution whole earth blue marble image, which is embedded in the worldwind jar and thus preloaded with the applet.
In the applet init()
// Add a BMNG base layer to the model layer list, before the Blue Marble insertBeforeLayerName(this.wwd, new BMNGOneImage(), "Blue Marble");
Additional methods
public static void insertBeforeLayerName(WorldWindow wwd, Layer layer, String targetName) { // Insert the layer into the layer list just before the target layer. int targetPosition = 0; LayerList layers = wwd.getModel().getLayers(); for (Layer l : layers) { if (l.getName().indexOf(targetName) != -1) { targetPosition = layers.indexOf(l); break; } } layers.add(targetPosition, layer); }
Note : the applet tag is considered deprecated in favor of the object tag :
DEPRECATED EXAMPLE: The following sample Java applet: <APPLET code="AudioItem" width="15" height="15"> <PARAM name="snd" value="Hello.au|Welcome.au"> Java applet that plays a welcoming sound. </APPLET> may be rewritten as follows with OBJECT: <OBJECT codetype="application/java" classid="AudioItem" width="15" height="15"> <PARAM name="snd" value="Hello.au|Welcome.au"> Java applet that plays a welcoming sound. </OBJECT>
Ref: HTML 4.01 Specifications, December 1999 : Applet
http://www.w3.org/TR/1999/REC-html401-19991224/struct/objects.html#h-13.4
Initial values can be passed to the applet using the param tag of the applet or oject tags:
<param name="paramName" value="some value">
From the applet class a parameter value can be retreived with the getParameter() method:
String paramValue = getParameter("paramName");
To allow javascript to 'talk' to the applet, first add an id attribute to the applet tag :
<applet id="wwjApplet" code="org.jdesktop.applet.util.JNLPAppletLauncher" width=600 height=400 ... >
To call an applet java method from javascript :
// Call someAppletMethod() via the launcher getSubApplet() method document.getElementById('wwjApplet').getSubApplet().someAppletMethod();
Note the use of the launcher getSubApplet() method to get at the applet itself. Javascript is really calling the launcher.
Important note for Mac : for javascript to be able to 'talk' to the applet, the applet-launcher.jar must be hosted on the same server as the applet. This means that if you need to have javascript/applet interaction across plateforms, you need to host a copy of applet-launcher.jar and keep it up to date.
When using the Next Generation Plugin, javascript will be able to access the applet directly without going through the applet launcher. For backward compatibility it is recommended to use the below code when accessing the applet:
var theApplet = null; function getWWJApplet() { if (theApplet == null) { theApplet = document.getElementById('wwjApplet'); } // See if we're using the old Java Plug-In and the JNLPAppletLauncher try { theApplet = theApplet.getSubApplet(); } catch (e) { // Using new-style applet -- ignore } return theApplet; } // Call someAppletMethod() via the getWWJApplet() method getWWJApplet().someAppletMethod();
Ref: Java Plugin Guide : JavaScript to Java Communication (Scripting)
http://java.sun.com/j2se/1.5.0/docs/guide/plugin/developer_guide/js_java.html
To allow the applet to access javascript or the document object, add the mayscript attribute to the applet tag :
<applet mayscript code="org.jdesktop.applet.util.JNLPAppletLauncher" width=600 height=400 ... >
To perform a call to javascript from the applet class use JSObject.getWindow():
import netscape.javascript.*; ... JSObject win = JSObject.getWindow(this); win.call("functionName", null); // calls javascript functionName() or win.eval("alert('An alert message')"); // evaluates and executes some javascript code as a string
Ref: Java Plugin Guide : Java-to-Javascript Communication
http://java.sun.com/j2se/1.5.0/docs/guide/plugin/developer_guide/java_js.html
To sign your archive files, you need to use keytool and jarsigner from your JDK bin folder.
Assuming the path to keytool and jarsigner is in the PATH environment variable.
Create a certificate (once):
Signing a jar :
Note : this example creates the certificate in the same folder as the applet. This is not necessary.
Ref: How to Sign Applets Using RSA-Signed CertificatesSigning archive files
.../WWJ Applet>keytool -genkey -keyalg rsa -alias yourname
Enter pw : ******
.../WWJ Applet>keytool -export -alias yourname -file yourname.crt
.../WWJ Applet>jarsigner worldwind.jar yourname
Enter pw : ******
http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/rsa_signing.html
This code bit may be usefull in some situations.
Policy.setPolicy(new Policy() { public void refresh() { } public PermissionCollection getPermissions(CodeSource arg0) { Permissions perms = new Permissions(); perms.add(new AllPermission()); return (perms); } });
We've received reports of the following issues occuring occassionaly
Note: Memory leaks have been reported when launching several applets in different tabs or when reloading the same applet page. Most of these issues have been solved with the Next Generation Pugin available since Java 6_10.
IGE, France
http://www.ige.fr/3d/WW/WWJ.php
Pred, France
http://atpred.free.fr/applet.html
GIS Solution, Italy
http://www.gis-solution.com/WWApplet/WWApplet.htm
July 2007 - Patrick Murris
First version
January 2009 - Patrick Murris
Updated for Next Generation Plugin