Open source Java projects: JFXtras

Utilities and add-ons for the JavaFX Script programming language

JavaFX is a rapidly maturing technology, but its capabilities are still limited. In this installment of Open source Java projects, Jeff Friesen introduces you to JFXtras, utilities and add-ons that fill in useful features that are absent in JavaFX 1.0.

JavaFX 1.0 is missing a lot of functionality, especially in regard to UI components and layouts. To address these deficiencies, developer Stephen Chin initiated the JFXtras project in late 2008. He released JFXtras 0.1 shortly after JavaFX 1.0 debuted. This initial JFXtras release introduced dialog boxes, more layouts, a unit-testing framework, and asynchronous thread support to JavaFX.

The JFXtras 0.2 milestone, released in January 2009, adds a new library of custom shapes via integration with Andres Almiray's jSilhouette Project, and it enhances 0.1's Grid layout, unit-testing framework, and more. With 0.3's release on February 17 (shortly after this article's completion), JFXtras is becoming an increasingly significant part of the JavaFX landscape.

This article focuses on JFXtras 0.2. After introducing you to the project's software distribution, I demonstrate how to use the software via the NetBeans and command-line versions of JavaFX. I then explore JFXtras' various features, ranging from asynchronous thread support and a custom shapes library to unit testing and utilities classes.

Open source licenses

Each of the Java projects covered in this series is subject to an open source license, which you should understand before integrating the project with your own projects. JFXtras is subject to the updated Berkeley Software Distribution (BSD) License. It is not subject to the simplified variant of this license or to any other license.

Getting started with JFXtras

The JFXtras project site's downloads page provides links for downloading JFXtras-0.2.jar and JFXtras 0.2.zip. If you're interested in the custom shapes library, you must download the ZIP file, which includes JFXtras-0.2.jar and two other JAR files that provide the jSilhouette scene graph infrastructure for custom shapes. If custom shapes are of no interest to you, you can download JFXtras-0.2.jar instead, but I recommend downloading JFXtras 0.2.zip. This archive's JFXtras 0.2 home directory contains the ChangeLog.txt, JFXtras-0.2.jar, and LICENSE.txt files. It also contains javadoc (API documentation), lib (jsilhouette-geom-0.3.jar and jsilhouette-scene-0.3.jar, custom shapes support JARs), src (JFXtras source code), and test (scripts for unit-testing JFXtras) subdirectories.

In addition to JFXtras 0.2, you need to install either NetBeans IDE 6.5 with JavaFX 1.0 or the JavaFX 1.0 SDK (if not already installed). Also, Windows platforms should have Java SE 6u10 or a higher update installed, whereas Macintosh platforms will benefit from Java 10.5 Update 2 (1.6.0_07). I developed this article's code with both JavaFX SDKs and Java SE 6u12 on a Windows XP SP3 platform.

A simple script

Before exploring JFXtras, let's play with a couple of examples, to familiarize you with developing scripts in the context of the NetBeans and command-line versions of JavaFX 1.0. For our first example, check out Listing 1.

Listing 1. Main.fx for a CharSeq project

/*
 * Main.fx
 */

package charseq;

import org.jfxtras.util.*;

def digits = SequenceUtil.characterSequence ("0", "9");
println (digits) // Output: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

This script invokes the SequenceUtil class's characterSequence() function to generate a sequence of single-character Strings from 0 through 9. You'll learn about characterSequence() and other SequenceUtil functions later in the article.

You'll probably prefer to work in the NetBeans environment, so complete the following steps to compile and run this script using NetBeans IDE 6.5 with JavaFX 1.0:

  1. Use the New Project wizard to introduce a CharSeq project with charseq.Main as the main file.
  2. Replace the generated skeletal Main.fx with Listing 1.
  3. Right-click CharSeq in the Projects window and select Properties from the pop-up menu.
  4. Select the Libraries category on the resulting Project Properties dialog box.
  5. Click the Add JAR/Folder button.
  6. Locate the appropriate directory containing JFXtras-0.2.jar and add this JAR to the Libraries list.
  7. Dismiss the Project Properties dialog.
  8. Click the green triangle button on the main toolbar, or press F6 to run the script.

If you would rather work at the command line, complete the following (Windows-oriented) steps to compile and run this script using the command-line version of JavaFX:

  1. Create a charseq subdirectory of the current directory.
  2. Copy Listing 1 to a Main.fx file and store this file in charseq.
  3. Copy JFXtras-0.2.jar to the current directory.
  4. Compile Main.fx via javafxc -cp JFXtras-0.2.jar charseq\Main.fx.
  5. Run the script via javafx -cp JFXtras-0.2.jar;. charseq.Main.

A shape-oriented script

When working with JFXtras, you'll often only need to access JFXtras-0.2.jar. However, if you're planning to work with custom shapes, as is the case with Listing 2, you'll also need to access jsilhouette-geom-0.3.jar and jsilhouette-scene-0.3.jar.

Listing 2. Main.fx for an Asterisk project

/*
* Main.fx
 */

package asterisk;

import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import org.jfxtras.scene.shape.Asterisk;

Stage
{
    title: "Centered Asterisk"
    width: 250
    height: 250

    var sceneRef: Scene
    scene: sceneRef = Scene
    {
        content: Asterisk
        {
            centerX: bind sceneRef.width/2.0
            centerY: bind sceneRef.height/2.0
            radius: 80
            width: 20
            beams: 5
            roundness: 0.5
            fill: Color.RED
        }
    }
}

This script creates a scene consisting of a single five-legged red asterisk shape whose center is always bound to the center of the scene. You'll learn about Asterisk and other custom shape classes later in this article.

Custom shapes glitches

If you're working on a Windows platform and using JavaFX 1.0 with Java SE 6u7 (the earliest JRE that JavaFX runs on for Windows), you may notice some strange glitches with JFXtras' custom shapes. For example, when I tried to run Listing 2 with Java SE 6u7, the asterisk was not painted properly, nor was it centered in the client area.

Follow the steps below to build and run this script from NetBeans:

  1. Use the New Project wizard to introduce an Asterisk project with asterisk.Main as the main file.
  2. Replace the generated skeletal Main.fx with Listing 2.
  3. Right-click Asterisk in the Projects window and select Properties from the pop-up menu.
  4. Select the Libraries category on the resulting Project Properties dialog box.
  5. Click the Add JAR/Folder button.
  6. Locate the appropriate directory containing JFXtras-0.2.jar and add this JAR to the Libraries list.
  7. Click the Add JAR/Folder button a second time.
  8. Change to the lib subdirectory containing jsilhouette-geom-0.3.jar and add this JAR to the Libraries list.
  9. Click the Add JAR/Folder button a third time.
  10. Add jsilhouette-scene-0.3.jar to the Libraries list.
  11. Dismiss the Project Properties dialog.
  12. Click the green triangle button on the main toolbar, or press F6 to run the script.

Figure 1 shows the resulting window with its asterisk shape.

The asterisk always appears in the window's center no matter how you resize the window
Figure 1. The asterisk always appears in the window's center no matter how you resize the window.

Follow the steps below to build and run this script using the command-line version of JavaFX:

  1. Create an asterisk subdirectory of the current directory.
  2. Copy Listing 2 to a Main.fx file and store this file in asterisk.
  3. Copy JFXtras-0.2.jar to the current directory.
  4. Create lib as a subdirectory of the current directory.
  5. Copy jsilhouette-geom-0.3.jar and jsilhouette-scene-0.3.jar to lib.
  6. Compile Main.fx via javafxc -cp JFXtras-0.2.jar asterisk\Main.fx.
  7. Run the script via javafx -cp JFXtras-0.2.jar;. asterisk.Main.

Exploring JFXtras

JFXtras 0.2 consists of nearly 50 classes organized into 10 packages, with each package name beginning with the org.jfxtras prefix. This section briefly examines some of these classes. For complete details, check out the API documentation in JFXtras 0.2.zip's javadoc directory, or point your browser to the  online Javadoc.

Asynchronous thread support

JavaFX Script is a single-threaded language. On Swing-based platforms, the event-dispatching thread runs JavaFX code. When this thread is delayed, such as when it's waiting for a Web-based document to download, the user interface's responsiveness suffers. To overcome this problem, you'll want to perform time-consuming operations on a background thread.

The nature of JavaFX's implementation makes it potentially dangerous to subclass Java's Thread class and start a background thread based on this subclass. Instead, you'll typically need to subclass JavaFX's AbstractAsyncOperation class (see James Clarke's JavaFX Async operations blog post for an example) if its RemoteTextDocument subclass doesn't meet your needs.

Subclassing AbstractAsyncOperation is somewhat cumbersome, especially when you find yourself coding part of the subclass's implementation in Java (to avoid unintended conflicts with binding, triggers, and the rest of the JavaFX runtime). Fortunately, you can avoid this challenge by taking advantage of JFXtras' org.jfxtras.async.JFXWorker class, which offers a general-purpose solution.

JFXWorker uses Java SE 6's SwingWorker class to execute an asynchronous operation on a background thread and make the result available on the event-dispatching thread. The asynchronous operation is described via a function assigned to JFXWorker's inBackground attribute. When the operation completes, JFXWorker invokes the function assigned to the onDone attribute.

The function assigned to inBackground returns an object (or null), which is then passed as an argument to onDone's function after inBackground's function successfully completes. However, if inBackground's function throws an exception, the function assigned to the onFailure attribute is invoked instead of onDone's function.

Listing 3 demonstrates JFXWorker's usefulness in the context of searching all files for a specific text string.

1 2 3 4 Page
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more