By James L. Weaver
This article, which is part one of a two-part series, focuses on using best practices for developing enterprise applications in JavaFX 2.0.
Downloads:
: Java FX
JavaFX 2.0 is an API and runtime for creating Rich Internet Applications (RIAs). JavaFX was introduced in 2007, and version 2.0 was released in October 2011. One of the advantages of JavaFX 2.0 is that the code can be written in the Java language using mature and familiar tools.
This article, which is part one of a two-part series, focuses on using best practices for developing enterprise applications in JavaFX 2.0.
To illustrate some best practices for enterprise application development in JavaFX 2.0, a sample application named TweetBrowser will be examined. As shown in Figure 1, this application contains the following:
The TweetBrowser project, which you'll download in the next section, contains the code for this application, portions of which we’ll highlight during the course of this article.
Figure 1: Screen Capture of the TweetBrowser Application at Startup
When you click a #hashtag or @screenname, a spinning progress indicator, as shown in Figure 2, appears in the upper right corner of the UI indicating that a search is in progress. You can also type a #hashtag, @screenname, or word in the text field and press the Enter key or click the Search button. Either way, the Search button’s appearance changes to an X to indicate that you can cancel the search by clicking the button, and most of the UI is disabled.
Figure 2: Screen Capture of TweetBrowser During a Search
Clicking a Web link in a tweet opens a pop-up window that contains a WebView with the chosen page, as shown in Figure 3.

Figure 3: A WebView After Clicking a Hyperlink
Note: You can obtain the NetBeans IDE from the NetBeans site.

Figure 4: Opening the TweetBrowser Project in NetBeans

Figure 5: Running the TweetBrowser Program in NetBeans
The TweetBrowser application should appear in a window, as shown previously in Figure 1. Go ahead and play with the application, navigating screen names, hashtags, and Web links. We’ll analyze the application and walk through some code next.
Before diving into the code, let’s analyze the pieces shown in Figure 6, which comprise the TweetBrowser application.

Figure 6: Diagram of the TweetBrowser Application
Starting from the top-right of Figure 6, the TweetBrowser home page is where the user launches the application by clicking the bug-eyed bird icon. This causes the application to be invoked via Java Web Start if an instance of TweetBrowser isn’t already running. Please refer to the “See Also” section for the URL of the TweetBrowser home page.
At the bottom left of Figure 6 is a representation of the tweetbrowser.ui package, which contains two Java classes and a JavaFX cascading style sheet (CSS):
At the bottom center of Figure 6 is a representation of the tweetbrowser.model package, which contains three Java classes:
As indicated in Figure 6, classes in the tweetbrowser.ui package invoke methods of classes in the tweetbrowser.model package. In addition, classes in the tweetbrowser.ui package render the state of the model to the UI, largely by utilizing the binding capabilities of JavaFX.
Some techniques and best practices used in the TweetBrowser application will be discussed in this section, namely the following:
We’ll start out with the first item in the list: invoking the application via Java Web Start from an application’s home page.
One of the attractive features of browser-based applications is that they are instantly available at given Web pages. Users have come to expect this, so one way to increase the comfort level of a user who is accessing a rich-client Java application is to offer a Java Web Start link on a Web page. In this way, the user experience can be very similar to running a Web application, because clicking an icon opens a window that contains the application. From the user perspective, the new window contains the application, without regard to the type of window it is (a browser window or a Java application window).
Listing 1 shows the HTML and JavaScript source for the TweetBrowser application home page, modified from the output of building the TweetBrowser project in NetBeans.
<html><head>
<script src="http://java.com/js/dtjava.js"></script>
<script>
function launchApplication(jnlpfile) {
dtjava.launch( {
url : 'TweetBrowser.jnlp'},
{
javafx : '2.0+'
},
{}
);
return false;
}
</script>
</head>
<body style="font-family: Arial; font-size: 12pt;">
<h2 >TweetBrowser Home Page</h2>
<a href='#'><img title="Launch TweetBrowser app"
src="img/tweetbrowser-logo-100.png"
onclick="return launchApplication('TweetBrowser.jnlp');"/></a>
<p>Click the icon to launch TweetBrowser via Java Web Start</p>
</body></html>
Listing 1: Example HTML and JavaScript Code for an Application Home Page
Listing 2 contains example source code for the Java Network Launching Protocol (JNLP) that launches the TweetBrowser application, also modified from the output of building the TweetBrowser project in NetBeans.
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0" xmlns:jfx="http://javafx.com" href="TweetBrowser.jnlp">
<information>
<title>TweetBrowser</title>
<vendor>Jim Weaver</vendor>
<description>Sample JavaFX 2.0 application.</description>
<offline-allowed/>
</information>
<resources os="Windows" arch="x86">
<jfx:javafx-runtime version="2.0+"
href="http://download.oracle.com/otn-pub/java/javafx/...code omitted..."/>
</resources>
<resources os="Windows" arch="x64">
<jfx:javafx-runtime version="2.0+"
href="http://download.oracle.com/otn-pub/java/javafx/...code omitted..."/>
</resources>
<resources>
<j2se version="1.6+" href="http://bit.ly/xyGWeN"/>
<jar href="TweetBrowser.jar" size="49305" download="eager" />
<jar href="lib/restfx-1.0.jar" size="49092" download="eager" />
<jar href="lib/restfx-server-1.0.jar" size="6884" download="eager" />
</resources>
<jfx:javafx-desc width="800" height="600"
main-class="javafxpert.tweetbrowser.ui.TweetBrowserMain"
name="TweetBrowser" />
<update check="background"/>
</jnlp>
Listing 2: Example Code for the JNLP That Launches the Application
The main difference between the source code generated by NetBeans and the source code shown in Listings 1 and 2 is that the applet-related code has been removed, making TweetBrowser available exclusively via Java Web Start.
Please refer to the Deploying JavaFX Applications guide mentioned in the “See Also” section for a detailed explanation of how to launch JavaFX applications via Java Web Start.
One consideration in using the Java Web Start approach is ensuring that only one instance of the application is invoked, regardless of whether the user clicks the application icon when an instance is already running. To accomplish this, the TweetBrowser application leverages some classes in the javafx.jnlp package, as shown in the start() method of TweetBrowserMain.java shown in Listing 3:
@Override public void start(final Stage primaryStage) {
stage = primaryStage;
try {
singleService =
(SingleInstanceService)ServiceManager
.lookup("javax.jnlp.SingleInstanceService");
singleListener = new SingleInstanceListener() {
@Override public void newActivation(String[] params) {
System.out.println("TweetBrowser instance already running");
primaryStage.toFront();
}
};
if (singleService != null) {
singleService.addSingleInstanceListener(singleListener);
}
}
catch (UnavailableServiceException use) {
singleService = null;
System.out.println("Single instance service not loaded");
}
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override public void handle(WindowEvent e) {
if (singleService != null) {
singleService.removeSingleInstanceListener(singleListener);
}
}
});
Scene scene = SceneBuilder.create()
.width(1000)
.height(660)
.stylesheets("javafxpert/tweetbrowser/ui/tweetbrowser.css")
.root(
BorderPaneBuilder.create()
.top(createToolBar())
.center(createListView())
.build()
)
.build();
listView.disableProperty().bind(TweetBrowserModel.instance
.queryActive.or(TweetBrowserModel.instance.webViewPopupVisible));
invokeSearch(FIRST_SEARCH_TERM, true);
createWebViewPopup();
progressIndicator.visibleProperty()
.bind(TweetBrowserModel.instance.queryActive
.or(TweetBrowserModel.instance.webViewPopupWebEngine
.getLoadWorker().runningProperty()));
stage.setScene(scene);
stage.setTitle("Tweet Browser");
stage.show();
}
Listing 3: The TweetBrowserMain.java start() Method
If the user attempts to start the application when a instance that was started via Java Web Start is already running, the overridden newActivation() method of the SingleInstanceListener is invoked rather than starting another instance of TweetBrowser. To clean up when the application is closing, the setOnCloseRequest() method of the primary window is supplied an event handler that removes the SingleInstanceListener.
Note: To satisfy the compiler, the jnlp.jar file is used in the project at compile time, but the javafx.jnlp classes shown in Listing 3 are available at runtime by the Java deployment toolkit.
Using the model/view/controller, or MVC, pattern has been a common practice in software development for many years. The JavaFX API facilitates the MVC pattern by providing the capability of binding properties of the UI to properties in the model.
As shown in Listing 4, the TweetBrowser application instantiates, and provides a reference to, the primary model class named TweetBrowserModel.
public class TweetBrowserModel {
public static TweetBrowserModel instance = new TweetBrowserModel();
public BooleanProperty queryActive = new SimpleBooleanProperty(false);
public BooleanProperty webViewPopupVisible =
new SimpleBooleanProperty(false);
public ObservableList allTweets = FXCollections.observableArrayList();
...
}
Listing 4: Instantiating and Referencing the Model
This reference is used in the TweetBrowserMain and TweetCell classes to bind the UI to the model. For example, the visibleProperty of progressIndicator in Listing 3 is bound to an expression involving the queryActive property of the model in Listing 4.
Another example of binding the UI to the model is shown in Listing 5, where the items property of listView is bound to the allTweets ObservableList in Listing 4.
private Node createListView() {
listView = ListViewBuilder.create()
.items(TweetBrowserModel.instance.allTweets)
.editable(false)
.build();
listView.setCellFactory(new Callback<ListView<Tweet>, ListCell<Tweet>>() {
@Override
public ListCell<Tweet> call(ListView<Tweet> list) {
ListCell tweetCell = new TweetCell();
tweetCell.setEditable(false);
return tweetCell;
}
});
return listView;
}
Listing 5: The TweetBrowserMain.java createListView() Method
Note that the binding behavior is built in to the items property of the ListView control, so the bind method isn’t used in this case.
Implementing techniques such as invoking an application via Java Web Start from the application’s home page, ensuring only one instance of the application is started, and binding the UI to the model make life easier for both the user and the developer.
In part two of this series, we’ll explore more techniques and best practices used in the TweetBrowser example application.
James L. (Jim) Weaver is a Java and JavaFX developer, author, and speaker with a passion for helping rich-client Java and JavaFX become preferred technologies for new application development. Books that Jim has authored include Inside Java, Beginning J2EE, and Pro JavaFX 2. His professional background includes 15 years as a systems architect at EDS, and the same number of years as an independent developer. As an Oracle Java Evangelist, Jim speaks internationally at software technology conferences, including the JavaOne conferences in San Francisco and São Paulo. Jim blogs at http://javafxpert.com, tweets @javafxpert, and may be reached at james.weaver AT oracle.com.
