JavaFX 2.0: A Platform for Rich Enterprise Client Apps

JavaFX 2.0 revamped the Java API for application development, discarding its predecessor’s clumsy scripting language. This enhancement has captured the attention of developers to rethink JavaFX 2.0 as a platform for creating and deploying rich client applications. Developers can now leverage their existing Java skills without worrying about spaghetti scripting code. JavaFX 2 can run either as a standalone desktop application or in the browser. The architecture is extensible with existing Swing or the SWT API.

JavaFX 2.0 is a rich client platform designed to provide an environment that not only minimizes development time but also eases the deployment of data-driven business and enterprise client applications.

JavaFX 2.0 Architectural Overview

JavaFX 2.0 is comprised of several subcomponents, including a high-performance graphics engine named Prism. Prism is the byproduct of a Mozilla Labs experiments to bridge the gap in user experience between Web applications and desktop apps. JavaFX also includes the Glass window toolkit, a media engine and a Web engine.

  • The JavaFX public API provides freedom and flexibility in creating rich client applications. Since JavaFX 2 includes the capabilities of the Java platform, it can leverage the power of Java features such as annotations, multi-threading, generics, and the extended Java collection library. Most of the API and programming model have been ported directly as a lineage of its predecessor, while some APIs such as Layout and Media have been optimized and simplified in response to the feedback from previous FX users.
  • Scene graph is the starting point of JavaFX 2.0 application. It is responsible for rendering user interfaces and handling user input through various visual elements represented as hierarchical tree of nodes. Each item in the scene graph is called a node and has one parent and zero or more children. The javafx.scene API simplifies working with rich UIs.
  • The Quantum Toolkit connects Prism and Glass Windowing Toolkit together to make them available to the JavaFX layer above them in the stack and also manages the threading rules related to rendering versus events handling.
  • Prism is responsible for rasterization and rendering of JavaFX scenes and processes rendering jobs. It can run on both hardware and software renderers, including 3-D.
  • Glass Windowing Toolkit’s main responsibility is to provide native operating services, such as managing the windows, timers and surfaces. It serves as the platform-dependent layer that connects the JavaFX platform to the native operating system. The Glass toolkit is also responsible for managing the event queue.
  • The Media Engine component has been completely redesigned for JavaFX 2.0 to increase stability, improve performance and provide consistent behavior across platforms.
  • Web Engine component is based on Web Kit, an open source Web browser engine that supports HTML5, CSS, JavaScript, DOM and SVG. It enables developers to implement features such as rendering HTML content, support history, back and forward navigation, execute JavaScript command and event handling in their Java applications.

JavaFX 2.0 Key Features

  • JavaFX APIs: Many API features are carried over from the Java language, such as use of generics, annotations, multi-threading and collections classes. Collections are defined by the javafx.collections package consisting of the following interfaces and classes:
    • JavaFX Interfaces
      • ObservableList: It is a list that enables listeners to track changes at the time of occurrence
      • ListChangeListener: It is an interface that receives notifications of changes to an ObservableList
      • ObservableMap: It is a map that enables observers to track changes when they occur
      • MapChangeListener: It is an interface that receives notifications of changes to an ObservableMap
    • JavaFX Classes
      • FXCollections: It is an utility class consists of static methods that are mapped copies of java.util.Collections methods
      • ListChangeListener.Change: It represents a change made to an ObservableList
      • MapChangeListener.Change: It represents a change made to an ObservableMap

    The close integration between JavaFX and the Java API has enabled developers to leverage sophisticated Java IDEs, debuggers and profilers in building rich client applications.

  • FXML: FXML is a scriptable, XML-based markup language that provides the structure for building a user interface separate from the application logic. This separation of the presentation and application logic will particularly enrich Web developers in building rich client apps because they can assemble a user interface that leverages Java components without mastering the code for fetching and filling in the data. However, it can also be used as an alternative for developing user interfaces programmatically in Java. This scripting feature allows embedding scripts within a FXML file. Any JVM scripting language such as JavaScript, Groovy or Clojure can be used to access FXML script for the purpose.
  • Graphics Pipeline for Modern GPUs: It is convenient to build rich graphics with support for high-level APIs, such as blurs, shadows, 2D /3D transformation, effects, charts and reflections. The windowing toolkit gets hardware accelerated graphics pipeline support from Prism. And for unsupported graphics hardware, there is also provision for support by the Java 2D software pipeline. The animation engine is optimized to implement transitions with complete overhaul of the API to simplify usage.
  • Set of Rich UI Controls: There are more than 50 components for form-based UI, including charts, layout and form controls. User Interface Controls are specialized Nodes in the JavaFX Scene graph suited for reuse in many different application contexts. Cascading Style Sheet (CSS) can be used effectively to design the look and feel and layout of user interface controls. The JavaFX UI controls available through the API are built by using nodes in the scene graph. Thus the controls can use visually rich features of the JavaFX platform. As the JavaFX APIs is fully implemented in Java, it is easy to integrate the JavaFX UI controls into existing Java applications.
  • Web Component: JavaFX 20 introduced the embedded browser, which provides not only a Web viewer but also full browsing functionality through its API. The embedded browser component is based on WebKit, an open source Web browser engine. It supports Cascading Style Sheets (CSS), JavaScript, Document Object Model (DOM), and some features of HTML5, including rendering canvas and timed media playback. The embedded browser enables developers to perform the following tasks in their applications:
    • Render HTML content from local and remote URLs
    • Execute JavaScript commands
    • Access document model from Java code
    • Handle events
    • Manage web pop-up windows
    • Apply effects to the embedded browser

    Web content can be embedded in JavaFX applications. Integration of WebKit has made HTML and JavaScript rendering fluid, in addition to providing DOM access and manipulation from Java.

  • Powerful Properties Model: JavaFX 2.0 also introduced a new set of collections, such ObservableList, Sequence and ObservableMap, which can be used effectively in cooperation with the existing Collection classes of Java. In addition, introduced new design and implementation of bean properties and a low-level binding API for high performance lowering footprint bindings.

Sample JavaFX App: Rich Client Interface Demo

Following is a JavaFX 2 tutorial that creates a pie chart and bar chart according to the user input into the TextField of estimated cost and actual cost of a hypothetical visual analysis of estimated budget versus actual expense.

/** Import statements and package declarations*/package org.event.budget;import java.util.Calendar;import java.util.Random;import javafx.application.Application;import javafx.collections.FXCollections;import javafx.collections.ObservableList;import javafx.event.*;import javafx.geometry.Insets;import javafx.scene.Scene;import javafx.scene.chart.BarChart;import javafx.scene.chart.CategoryAxis;import javafx.scene.chart.NumberAxis;import javafx.scene.chart.PieChart;import javafx.scene.chart.XYChart;import javafx.scene.control.*;import javafx.scene.image.Image;import javafx.scene.image.ImageView;import javafx.scene.layout.*;import javafx.scene.text.Font;import javafx.scene.text.FontWeight;import javafx.scene.text.Text;import javafx.stage.Stage;/** Starting application class*/public class TallyReport extends Application {/** private members declaration*/String bgcolor = "-fx-background-color: DAE6F3";private Label lblEstTot = new Label("");private Label lblActTot = new Label("");private BorderPane border = null;private GridPane grid = null;private String label[] = { "Site", "Decoration", "Publicity", "Misc.","Refreshments", "Program", "Prizes" };private TextField tfEstimated[] = new TextField[label.length];private TextField tfActual[] = new TextField[label.length];private PieChart estimateChart = new PieChart();private PieChart actualChart = new PieChart();private CategoryAxis xAxis = new CategoryAxis();private NumberAxis yAxis = new NumberAxis();private BarChart bc = new BarChart(xAxis,yAxis);/** Main method*/public static void main(String[] args) {Application.launch(args);}/** JavaFX application starts from the start(...) function* Here stage is initialized and layout is arranged for the application*/@Overridepublic void start(Stage stage) throws Exception {stage.setTitle("Tally Budget");border = new BorderPane();border.setStyle(bgcolor);TabPane tabPane = new TabPane();Tab tab1 = new Tab("Estimated Cost Breakdown");tab1.setClosable(false);tab1.setContent(estimateChart);Tab tab2 = new Tab("Actual Cost Breakdown");tab2.setClosable(false);tab2.setContent(actualChart);tabPane.getTabs().addAll(tab1, tab2);border.setRight(tabPane);VBox vbox = new VBox();vbox.setStyle(bgcolor);vbox.getChildren().addAll(initInputSection(), bc);border.setCenter(vbox);/** This may be removed to feed random value into the formfeedRandomValue();*/stage.setScene(new Scene(border, 1000, 600));estimatedPieChart();actualPieChart();barChart();Integer etot = 0;Integer atot = 0;for (int i = 0; i < label.length; i++) {etot += Integer.parseInt(tfEstimated[i].getText());atot += Integer.parseInt(tfActual[i].getText());}lblEstTot.setText("$ " + etot.toString());lblActTot.setText("$ " + atot.toString());stage.show();}/** Input form is created*/public GridPane initInputSection() {grid = new GridPane();grid.setHgap(2);grid.setVgap(4);grid.setPadding(new Insets(10, 10, 10, 50));Text title = new Text("Estimated Vs Actual Cost");title.setFont(Font.font("Tahoma", FontWeight.BOLD, 20));grid.add(title, 1, 1, 3, 1);Text estimated = new Text("Estimated Cost");estimated.setFont(Font.font("Tahoma", FontWeight.BOLD, 10));grid.add(estimated, 2, 2, 2, 1);Text actual = new Text("Actual Cost");actual.setFont(Font.font("Tahoma", FontWeight.BOLD, 10));grid.add(actual, 3, 2, 2, 1);Tooltip tip = new Tooltip("Enter numeric value");tip.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("fileinfo-32.png"))));for (int i = 0; i < label.length; i++) {grid.add(new Label(label[i]), 1, i + 3);tfEstimated[i] = new TextField("20");tfEstimated[i].setPromptText("0");tfEstimated[i].setTooltip(tip);tfActual[i] = new TextField("20");tfActual[i].setPromptText("0");tfActual[i].setTooltip(tip);grid.add(tfEstimated[i], 2, i + 3);grid.add(tfActual[i], 3, i + 3);}lblEstTot.setFont(Font.font("Tahoma", FontWeight.BOLD, 12));lblActTot.setFont(Font.font("Tahoma", FontWeight.BOLD, 12));grid.add(lblEstTot, 2, 11);grid.add(lblActTot, 3, 11);Button btn = new Button("Calculate and create Chart");btn.setOnAction(new EventHandler() {public void handle(ActionEvent event) {/** This may be removed to feed random value into the form on button clickfeedRandomValue();*/estimatedPieChart();actualPieChart();barChart();Integer etot = 0;Integer atot = 0;for (int i = 0; i < label.length; i++) {etot += Integer.parseInt(tfEstimated[i].getText());atot += Integer.parseInt(tfActual[i].getText());}lblEstTot.setText("$ " + etot.toString());lblActTot.setText("$ " + atot.toString());}});grid.add(btn, 3, 12);return grid;}/** Pie chart is created here for breakdown of estimated cost*/public void estimatedPieChart() {estimateChart.getData().clear();ObservableListpieChartData = FXCollections.observableArrayList();for (int i = 0; i < label.length; i++) {pieChartData.add(new PieChart.Data(label[i], Integer.parseInt(tfEstimated[i].getText())));}estimateChart.setStyle(bgcolor);estimateChart.setData(pieChartData);estimateChart.setAnimated(true);estimateChart.setTitle("Estimated Cost Breakdown");}/** Pie chart is created here for breakdown of actual expense*/public void actualPieChart() {actualChart.getData().clear();ObservableListpieChartData = FXCollections.observableArrayList();for (int i = 0; i < label.length; i++) {pieChartData.add(new PieChart.Data(label[i], Integer.parseInt(tfActual[i].getText())));}actualChart.setStyle(bgcolor);actualChart.setData(pieChartData);actualChart.setAnimated(true);actualChart.setTitle("Actual Cost Breakdown");}/** Bar chart is created here for tallying estimated vs. actual expenses*/@SuppressWarnings({ "unchecked", "rawtypes" })public void barChart() {bc.getData().clear();bc.setAnimated(true);bc.setTitle("Estimated Vs Actual Cost");xAxis.setLabel("Estimated Vs Actual Cost");yAxis.setLabel("Cost");XYChart.Series series1 = new XYChart.Series();series1.setName("Estimated Cost");for (int i = 0; i < label.length; i++)series1.getData().add(new XYChart.Data(label[i], Integer.parseInt(tfEstimated[i].getText())));XYChart.Series series2 = new XYChart.Series();series2.setName("Actual Cost");for (int i = 0; i < label.length; i++)series2.getData().add(new XYChart.Data(label[i], Integer.parseInt(tfActual[i].getText())));bc.getData().addAll(series1, series2);}/*** This may be removed to feed random value into the form*public void feedRandomValue() {Random r = new Random(Calendar.getInstance().getTimeInMillis());for (int i = 0; i < label.length; i++) {int n = r.nextInt() % 5000;if (n < 0)n = n * -1;tfEstimated[i].setText(String.valueOf(n));n = r.nextInt() % 5000;if (n < 0)n = n * -1;tfActual[i].setText(String.valueOf(n));}}*/}

Conclusion

The most important upgrade in JavaFX 2.0 is obviously its seamless integration of the JavaFX API with the Java API. Though scripting has its use, as a programmer I never liked JavaFX before. Though it will take some time to attain maturity in the market, JavaFX 2.0 is definitely worth considering when building rich enterprise client applications. It features data visualization, media streaming, seamless integration of Web content, hardware accelerated graphics, animations, effects, a rich set of UI controls. and more. The added advantage of JavaFX applications deployed within a browser page or as desktop applications is they can leverage the strengths of the underlying Java platform, including a robust security model, thousands of APIs, a high-performance virtual machine and years of optimization.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

microsoft careers

Top Careers at Microsoft

Microsoft has gained its position as one of the top companies in the world, and Microsoft careers are flourishing. This multinational company is efficiently developing popular software and computers with other consumer electronics. It is a dream come true for so many people to acquire a high paid, high-prestige job

your company's audio

4 Areas of Your Company Where Your Audio Really Matters

Your company probably relies on audio more than you realize. Whether you’re creating a spoken text message to a colleague or giving a speech, you want your audio to shine. Otherwise, you could cause avoidable friction points and potentially hurt your brand reputation. For example, let’s say you create a

chrome os developer mode

How to Turn on Chrome OS Developer Mode

Google’s Chrome OS is a popular operating system that is widely used on Chromebooks and other devices. While it is designed to be simple and user-friendly, there are times when users may want to access additional features and functionality. One way to do this is by turning on Chrome OS