NASA World Wind

Package gov.nasa.worldwind.examples.applet

NASA World Wind Java Applets

See:
          Description

Class Summary
WWJApplet Provides a base application framework for simple WorldWind applets.
WWJAppletMinimal Provides a base application framework for simple WorldWind applets.
 

Package gov.nasa.worldwind.examples.applet Description

NASA World Wind Java Applets

Last modified september 14, 2007

Introduction

This document is intended to help developers through the process of assembling and deploying a World Wind Java applet using Sun's JNLPAppletLauncher.

Requirements

As for the whole World Wind Java project, please check the following points :

JOGL applet setup can be tested with this sample Gears 3D JOGL animation applet:
https://jogl-demos.dev.java.net/applettest.html

Compiling and running a WWJ applet

All you need to deploy a WWJ applet is a web page with the proper html declarations, the WWJ SDK archive worldwind.jar, and possibly your special implementation of one of the applet templates in its own archive, eg. myapplet.jar.

    myapplet.html          Web page that loads the applet
    myapplet.jar           Optional applet class in its own archive
    worldwind.jar          World Wind Java SDK, including applet templates

With the JNLPAppletLauncher, all other needed components can be fetched from external servers : the launcher itself applet-laucher.jar, 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 the steps below :

  1. Use one of the world wind applet templates from the SDK (see code sample below).
  2. Compile and export worldwind.jar and, if needed, a separate jar for the applet.
  3. Sign all jars (see Signing below).
  4. Copy the jar(s) to your deployement folder.
  5. Run with a web page using the JNLPAppletLauncher (see below)

Important note for Mac : as of september 2007, the Java plugin for mac is still in version 5 - whereas other plateforms can run java 6. If you want to cover all plateforms you need to compile for java 5.

If your applet uses a custom World Wind configuration file, within a static block of your applet and before calling any World Wind method or constructor set the gov.nasa.worldwind.config.file Java property to the path of your configuration 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().

Known issues

First use :

After navigating to other pages and coming back

PRESUMABLY FIXED - 2007-07-27 : Applet is 'shut down' whenever the user navigates to another page. When coming back, it is restarted like a new one.

Code samples

WWJ Applet minimal class template

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.

Preloading a blue marble base image from the 'images' SDK folder

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 big void, add in the layer list, before 'blue marble' a full sphere SurfaceImage of a lower resolution whole earth blue marble image, that 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);
    }

Using JNLPAppletLauncher

Here is the htlm code to use in a web page 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, just add a reference to it in the archive attribute of the applet tag - like after worldind.jar, 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/

Applet vs object tag

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

Communication between the web page and the applet

Passing parameters to the applet

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");

Javascript to the applet

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.

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

Applet to javascript and the document object

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

Signing archive files

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):

.../WWJ Applet>keytool -genkey -keyalg rsa -alias yourname

Enter pw : ******

.../WWJ Applet>keytool -export -alias yourname -file yourname.crt

Signing a jar :

.../WWJ Applet>jarsigner worldwind.jar yourname

Enter pw : ******

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 Certificates
http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/rsa_signing.html

Security Policy

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);
            }
        });

WWJ Applet examples

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

Document history

July 2007 - Patrick Murris
First version


NASA World Wind