The new applet experience

Applet development with JavaFX Script and Java SE 6u10

Jeff Friesen puts the newer, faster applet to the test in this companion to his JavaWorld feature: "Are applets making a comeback?" Here you can get a short introduction to rich Internet applet development using JavaFX Script and key features of Java SE 6 update 10, including the Java Deployment Toolkit , Java Quick Starter, and the Java Kernel.

The historic problems of applets have been well-documented and we've looked in-depth at some of the efforts currently underway to revitalize them for a new generation of Java Web developers (see this article's companion "Are applets making a comeback?"). Still, it remains to be seen if the new technologies clustering under the umbrella of Java SE 6 update 10 beta (Java SE 6u10) are enough to improve applet performance and create a Java browser and desktop experience capable of competing with Flex and Silverlight.

In this short companion to my investigation of the possible applet comeback, I take a more hands-on approach to understanding the viability of Sun's efforts in the rich internet space, using JavaFX Script and Java SE 6u10 to create my own "rich Internet applet." As I think you'll learn by following this short development exercise with me, JavaFX Scrip and Java SE 6 update 10 do indeed make applet development and deployment a much better experience than the one many of us remember from the early days of Java.

Note that this exercise in applet development is based on a Windows XP platform environment.

Building a rich Internet applet

In my JavaWorld article "Ajax programming with the Java Scripting API," I presented a small Java application that utilizes the Java Scripting API and a pair of JavaScript-based scripts to obtain an RSS document, which contains weather data (from Yahoo! Weather) corresponding to a user-entered zip code. After parsing out the data, the application presents this data to the user.

For the purpose of learning, I've converted this rich Internet application (RIA) to an equivalent applet. Instead of writing the applet in Java, I wrote it using JavaFX Script (the compiled version of the language, whose syntax differs from the interpreted version), blending Java code with JavaFX Script's simplifying declarative syntax and convenient binding capability. As Listing 1 testifies, the JavaFX Script approach results in much less code to write, especially for the user interface.

Listing 1 Weather.fx

// Weather.fx

import java.lang.StringBuilder;

import javafx.ui.Applet;
import javafx.ui.BorderPanel;
import javafx.ui.Canvas;
import javafx.ui.Color;
import javafx.ui.CompoundBorder;
import javafx.ui.EmptyBorder;
import javafx.ui.EtchedBorder;
import javafx.ui.FlowPanel;
import javafx.ui.Image;
import javafx.ui.Label;
import javafx.ui.SimpleLabel;
import javafx.ui.StackPanel;
import javafx.ui.TextField;

import javafx.ui.canvas.ImageView;

import javafx.xml.Document;
import javafx.xml.DocumentBuilder;
import javafx.xml.Element;

class WeatherModel
{
   private attribute weatherFeedURIBase =
     "http://weather.yahooapis.com/forecastrss?p=";

   private attribute docBuilder = DocumentBuilder
                                  {
                                     namespaceAware: true
                                     validating: true
                                     ignoringComments: false
                                  };

   attribute labelHTML: String;

   function getRSSDocument (value: String): Void
   {
      var document = docBuilder.parseURI (weatherFeedURIBase.concat (value));
      var elems = document.getElementsByTagName ("description");

      var result = new StringBuilder ();
      result.append ("<html><center><b>");
      result.append (elems [0].value);
      result.append ("</b><br /><br />");

      if (elems [0].value.indexOf ("Error") == -1)
      {
          var desc = elems [1].value;
          var index = desc.indexOf ("<a");
          if (index <> -1)
              desc = desc.substring (0, index);

          result.append ("<table border=1 bgcolor=#ffffff><tr><td>");

          index = desc.indexOf ("<b>Current");

          result.append (desc.substring (0, index));
          result.append ("</td></tr></table><br />");
          result.append (desc.substring (index));
      }

      result.append ("</center></html>");

      labelHTML = result.toString ();
   }
}

Applet
{
   var wModel = WeatherModel {}

   content: BorderPanel
            {
               center: StackPanel
               {
                  content:
                  [
                     Canvas
                     {
                        content:
                        [
                           ImageView
                           {
                              image: Image
                              {
                                 url: "file:bg.jpg"
                              }
                           }
                        ]
                     }
                     ,
                     BorderPanel
                     {
                        top: FlowPanel
                             {
                                border: CompoundBorder
                                        {
                                           borders:
                                           [
                                              EmptyBorder
                                              {
                                                 bottom: 10
                                                 left: 10
                                                 right: 10
                                                 top: 10
                                              },
                                              EtchedBorder {},
                                              EmptyBorder
                                              {
                                                 bottom: 5
                                                 left: 5
                                                 right: 5
                                                 top: 5
                                              }
                                           ]
                                        }

                                var t: TextField

                                content:
                                [
                                   SimpleLabel
                                   {
                                      text: "Zip code"
                                   },
                                   t = TextField
                                   {
                                      columns: 5
                                      background: Color.WHITE

                                      action: function (): Void
                                              {
                                                 wModel.getRSSDocument (t.value);
                                              }
                                   }
                                ]
                             }

                        center: Label
                                {
                                   border: CompoundBorder
                                           {
                                              borders:
                                              [
                                                 EmptyBorder
                                                 {
                                                    bottom: 10
                                                    left: 10
                                                    right: 10
                                                    top: 10
                                                 },
                                                 EtchedBorder {},
                                                 EmptyBorder
                                                 {
                                                    bottom: 5
                                                    left: 5
                                                    right: 5
                                                    top: 15
                                                 }
                                              ]
                                           }

                                   text: bind wModel.labelHTML
                                }
                     }
                  ]
               }
            }
}

If you're unfamiliar with JavaFX Script, you might find Listing 1 challenging to grasp. This code basically creates a model (WeatherModel) and a UI (Applet's content attribute), and binds the model to the UI via text: bind wModel.labelHTML. This binding updates the UI's label component with labelHTML's content whenever this attribute is updated in response to wModel.getRSSDocument(t.value) calls.

1 2 3 4 Page 1
Page 1 of 4