Category Archives: JavaFX

FXMark, JavaFX, Nashorn and LinkedIn spam fail!

Just a quick note to fill you in on some recent developments…

First, FXMark (my JavaFX benchmarking and demo software) has been further delayed because I grossly underestimated the length of time it would take to unpack dozens of boxes of “stuff” when moving from one house to another and also because much of my time recently has been devoted to caring for a very sick family member.  On the good news, the family member’s health has stabilised somewhat and I now have a lot more time to devote to completing FXMark.  Stay tuned for a release in June!

On the JavaFX front itself, I have been exploring lots of the new features and especially playing around with Nashorn and its combination with Canvas.  I hope to be able to post some really impressive samples soon too!

Finally, after years of being pestered to create a LinkedIn account, I finally decided to have a go using my iPhone while sitting on the train.  It’s an understatement to say that this did not work out the way I had hoped.  For some reason, it seems that everyone in my address book(s) got sent a request to link with me, many of whom will regard this request as total and utter spam (and correctly so!). I even received a request from myself on my main and secondary email addresses!

The worst and by far the most embarrassing recipient was the entire OpenJFX developer mailing list!  Ouch! #epicfail

To all the good people on that list I offer my sincerest apologies!

Just my 2 bits

Felix

JavaFX: Why it matters even more with Java 8

I have previously blogged about the annoying prevalence of FUD surrounding JavaFX and unfortunately this article by Paul Krill titled “Sorry, JavaFX — Java 8 won’t help you matter” published on InfoWorld a couple of weeks or so ago is just another example (and a particularly bad one at that).

Given the number of glaring technical anomalies in the article, I am still in two minds as to whether it was just another anti-JavaFX trolling attempt or if the author simply just didn’t do their research.  It’s also possible that it was just a slightly late April Fools Joke given that it was published on April 2!

Either way, I do get angry when a supposedly reputable site like InfoWorld publishes such nonsense-ridden guff about a technology that I personally have invested a significant amount of time and effort into.

The article doesn’t start well with the opening salvo:

“The rich client technology has devotees, but analysts doubt its viability as the RIA space loses ground to mobile apps”

So what does JavaFX have to do with the “RIA space”, whatever that might be?  Admittedly the Wikipedia article on RIAs doesn’t help here but JavaFX is not a technology that is predominantly designed to run inside a web browser and is therefore not a RIA technology.  The concept of RIA is now almost entirely related to HTML5 as the previous contenders for plugin-based alternatives (namely Flash and Silverlight) gradually disappear into obscurity.

Krill declares that JavaFX is apparently both a “rich client technology” and a RIA (which in my dictionary is not possible) and that (whichever one it is) it is losing ground to mobile apps.  Well, this rather confusing statement highlights the real problem with JavaFX, namely that many in the community don’t really understand what it is or what it can be used for.

JavaFX is a technology for building applications with a Graphical User Interface (GUI) using JVM-based languages and doesn’t really care where or how that application is deployed or launched.  Currently it runs on all the major desktop operating systems such as Windows, MacOS & Linux as well as on embedded platforms such as Raspberry Pi and BeagleBoard and also runs on the mobile operating systems iOS and Android (although there is no official release for mobile platforms yet).

The support for JavaFX on mobiles and tablets is growing rapidly through technologies such as RoboVM for iOS and by utilising Dalvik itself for Android.  The RoboVM website states “RoboVM translates Java bytecode into native ARM or x86 code” and the Android port utilises the Dalvik classes themselves (remembering that Android already uses Java).  The point is that with both of these solutions, the actual applications running on mobile devices are just as native as any other apps developed for those platforms so it is just plain silly to claim that JavaFX is “losing ground to mobile apps”.  The beauty though of course is that you can take your JavaFX code base and then run applications derived from it on desktop, embedded and mobile platforms.

The article goes on to quote John Rymer of Forrester Research as saying:

“I’m afraid JavaFX is too little, too late. JavaFX certainly didn’t accomplish Sun’s goal for it, which was to make Java the top environment for Web client and mobile development.”

Well, there’s actually no evidence to support the outlandish claim that JavaFX is “too little, too late” because all of the platforms that JavaFX either currently runs on or will soon run on are still very relevant and I am guessing that applications running on those platforms together comprise about 99% of all existing software!  And what it is this “Web client” that he speaks of?  Whatever that is, I am pretty sure that Oracle (who purchased Sun Microsystems) have zero plans for JavaFX to be the “top environment” for it.  Web client equals HTML (4 & 5) and that is it.  Period.

The next ludicrous remark in the article is:

“Like Adobe Flash and Microsoft Silverlight, JavaFX has been pushed to the background.”

WTF? This is another of the major misconceptions about JavaFX, that it is just a competitor for Flash or Silverlight.  Well, JavaFX is not and never was just a competitor for these now declining technologies.  It is an entirely different class of product and given that it is not reliant on being deployed to run inside a browser, HTML5 poses absolutely no threat to its future relevance (see here for a previous article of mine about this).  JavaFX is not being “pushed to the background”; it is in fact growing and growing very rapidly.  It is true however that both Flash and Silverlight are on the inevitable path to oblivion.  Updating Flash on my Ubuntu machine this morning for example gave me a message to say that Flash 11.2 on Linux is the last version to be release by Adobe.  I didn’t get any such messages about JavaFX when I upgraded to Java 8!

The article then quotes another “luminary” in Michael Cote of 451 Research who further discredits the message with the quote:

“I think the days of the RIA are long gone and have evolved into what we call mobile and tablets. HTML5, Android, and, of course, iOS handily won.”

This statement by itself would have perfectly acceptable had he not prefaced it with the declaration that he “sees JavaFX as a fading rich Internet application technology”.  Given that I have already pointed-out that JavaFX apps on mobiles and tablets are true native apps for those platforms, the implied negative connotations of this statement regarding JavaFX can be disregarded completely.

Krill himself then trumps the stupidity of all the previous claims in the article with this doozy:

“Oracle has demonstrated JavaFX on Android and iOS, though the Java runtime itself is not permitted on iOS devices.”

The problems with this one are twofold.  First, as explained, the Java runtime does not need to run on these devices for JavaFX apps to be deployed there.  Secondly, there is actually no reason in 2014 why the Java runtime would not be permitted to run on iOS devices.  The actual limitation is that Just-In-Time (JIT) compilation is not permitted on iOS which is a very important distinction.

Anyway, even if the reader of the article were able to distinguish FUD from fact, perhaps the main deficiency in an article with “Java 8″ in the title is that it almost never mentions this latest and extremely significant update of the Java language and the improvements and enhancements in the version of JavaFX that is built-in to Java 8.  There is an absolute plethora of articles about the major and very important changes in Java 8 itself such as lambda expressions, streams, default methods in interfaces, the new date/time API and Nashorn (the high performance JVM-based JavaScript engine) and JavaFX has been updated to make use of many of these new features.

As for the new features of JavaFX 8 itself, Oracle’s page does a good job of describing them as:

  • The new Modena theme has been implemented in this release. For more information, see the blog at fxexperience.com.
  • The new SwingNode class enables developers to embed Swing content into JavaFX applications. See the SwingNode javadoc and Embedding Swing Content in JavaFX Applications.
  • The new UI Controls include the DatePicker and the TreeTableView controls.
  • The javafx.print package provides the public classes for the JavaFX Printing API. See the javadoc for more information.
  • The 3D Graphics features now include 3D shapes, camera, lights, subscene, material, picking, and antialiasing. The new Shape3D (Box, Cylinder, MeshView, and Sphere subclasses), SubScene, Material, PickResult, LightBase (AmbientLight and PointLight subclasses) , and SceneAntialiasing API classes have been added to the JavaFX 3D Graphics library. The Camera API class has also been updated in this release. See the corresponding class javadoc for javafx.scene.shape.Shape3D, javafx.scene.SubScene, javafx.scene.paint.Material, javafx.scene.input.PickResult, javafx.scene.SceneAntialiasing, and the Getting Started with JavaFX 3D Graphics document.
  • The WebView class provides new features and improvements. Review Supported Features of HTML5 for more information about additional HTML5 features including Web Sockets, Web Workers, and Web Fonts.
  • Enhanced text support including bi-directional text and complex text scripts such as Thai and Hindi in controls, and multi-line, multi-style text in text nodes.
  • Support for Hi-DPI displays has been added in this release.
  • The CSS Styleable* classes became public API. See the javafx.css javadoc for more information.
  • The new ScheduledService class allows to automatically restart the service.
  • JavaFX is now available for ARM platforms. JDK for ARM includes the base, graphics and controls components of JavaFX.

As you can see, it is very clear that both Java 8 and JavaFX 8 are major releases and that to say JavaFX is either “too little, too late” or “declining” is patently false.

On the contrary, JavaFX is growing and growing rapidly and has the very real potential to become the best toolkit for developing GUI applications and apps on a vast array of platforms from desktops and embedded to mobiles and tablets.

Since JavaFX 2, JavaFX has always mattered and now with Java 8, JavaFX most definitely matters even more!

Just my 2 bits

Felix

FXMark – JavaFX benchmarking software to be released soon

As some of you may have noticed, I have not posted in this blog for a few months and have not been able to release a product I have been working on for a while in my spare time.  This delay is mainly the result of me having been very occupied with building and moving into a new house.

Some months ago I tweeted about my plans for a product named FXMark which is a tool to both observe node-based animations in JavaFX and also to benchmark them.  In the absence of anything other than very simple animations in the JavaFX demo app Ensemble, I wanted to see for myself just how well the node-based animations available in JavaFX performed with multiple nodes and effects.  I have previously posted some demos of JavaFX Canvas animations which performed surprisingly well but I was unable to find any non-trivial samples online of node-based animations.

As you will see when I release FXMark, JavaFX node-based animations perform very well.  Here are some screenshots of some animations in progress with different settings:

FXMark Animations

FXMark Animations 2

Several options are available for configuring the animations such as those shown here:

FXMark Control Panel

The properties of the nodes (e.g. dimensions, stroke, colour etc.), animations (e.g. duration etc.) and effects (e.g. radius, offset, level etc.) are driven by random parameters based on either a deterministic sequence where Random is given a constant seed for consistent, reproducible results or a non-deterministic sequence using a different seed each time.

FXMark can be run as a benchmark where the actual animations run are governed by the settings in a configuration file or simply as an interactive application where the user can change the settings in real-time.

A report detailing the particular animations and their associated configurations will be produced that contains details of the resulting effects on frame rate (FPS) which will be the only metric available in v1.0.  However, other metrics will be captured in future releases by extracting additional information from PulseLogger.

I hope to be in a position to release FXMark 1.0 by the end of March 2014.

Just my 2 bits

Felix

JavaFX on iOS and Android: Six Degrees of Separation

Background

JavaOne for 2013 has just come and gone and there is much buzz within the JavaFX community in relation to the announcements made for this technology. Unfortunately, there is just as much buzz (if not more) that relates to announcements that weren’t made.  Specifically, another year has passed and we still have not heard from Oracle if/when they are releasing a port of JavaFX (or Java for that matter) for the significant mobile and tablet operating systems in iOS and Android.

Sadly, many have come to the conclusion that this is the beginning of the end for JavaFX and that Oracle “just don’t get it”. Well, I am fairly sure that Oracle do indeed “get it” and that JavaFX on iOS and Android will happen… eventually!

Is it too late for Oracle to release a JVM and JavaFX port for these platforms? No, it isn’t. Not by a long shot! The combination of the power of the Java platform & langauge, the rich APIs and the absolute awesomeness of JavaFX itself mean that when such a port is finally available it will actually be a much better toolkit to develop mobile applications than anything I can think of that currently exists (in any language). Plus, your apps will work on just about every hardware platform on the market today including devices ranging from Raspberry Pi to high-end workstations.

So, let’s hang in there for now. Personally I am “betting my house” on JavaFX and even though I don’t expect you to do the same, I would really like to encourage you to keep the faith.

OK, what follows is based on the assumption that sooner or later JavaFX will be running on iOS and Android (and well enough to support commercial app development).

I have come up with what are my six conditions which must be satisfied for any such port to be successful. You can think of them as a kind of “Six Degrees of Separation” in the sense that the more of them which are not satisfied then the more “separated” the JavaFX apps are from true native apps. And the greater the degree of separation, the lower the likelihood of success.

Here are the six conditions that must be satisfied by JavaFX apps when compared to native apps.

1. Their look and feel is indistinguishable from native apps

This is the most important of all the conditions. We must not repeat the mistakes of the past. By “mistakes” I refer to such situations that arose when the “native” Swing look-and-feel for Windows was released (for example). This look-and-feel was initially only vaguely similar to the native look and feel and it was extremely simple to identify a Swing app that was “pretending” to be a native app. There were so many visual inconsistencies and defects that end users were made to feel very uneasy using such apps. The fact that they were “impersonating” native apps only made this worse. In fact, I remember some people actually making a conscious decision not to purchase an app once they (easily) detected that it was a Swing/Java app.

So, to me, if there are any (unintentional) characteristics of a JavaFX app that make it easy to be identified as just that then this condition has not been met.

Please note that having the standard/default look-and-feel of the OS is not absolutely required for this condition to be met as there are many types of apps such as games or visualizations or any app of a nature where “standard” widgets are not prominent that can have their own stylised look-and-feel.

2. They must load as quickly as a native apps

These days most phone/tablet apps launch pretty quickly and users expect this. JavaFX apps must do the same. The challenge here is that a JavaFX app will have to load a substantial Java platform when it launches unless Oracle can figure out a way to load the “platform” once and then have it accessible by all Java apps on the device.

To put it simply, if your JavaFX app takes anything more than a few seconds to launch then this condition is not met.  Ideally, it will load almost instantaneously.

3. They must perform as well as a native apps once loaded

It’s all well and good to launch/load quickly but it is even more important that the app performs as well as a native app once it has been loaded and the user interacts with it.

Another problem with the “native” look-and-feels that ship with Swing is that even after many years of development whereby many of the visual inconsistencies were ironed-out, there was something not quite right about using such apps. For mine, whenever I used a Swing application with the Windows look-and-feel, there was always a tiny-but-perceptible “lag” every time I clicked on something, resized a window or simply navigated around the application that once again brought the fact that this was not a true native application into the front of my mind. Such delays/lags may not actually be longer than half a second or so and sound insignificant on paper but do indeed play an important role in the “user experience”.

So once again, if the user detects noticeable lagging or pausing in a JavaFX app then this condition is not met. Similarly, if rendering graphics or loading content is noticeably slower within a JavaFX app than within a native app then this condition has a “fail” mark next to it.

4. They must be able to utilise all (or at least most) of the native APIs, devices and features that native apps can utilise

Getting Java and JavaFX to run on iOS and Android is really only the start of what is required to have a toolkit/platform suitable for serious commercial software development.

For these types of devices in particular, it is absolutely vital that native APIs and native devices can be utilised by JavaFX applications. For example, on iOS there are several keyboard “styles” and configurations such as QWERTY, a numeric keypad and a keypad with symbols such as ‘@’ and “.com” for simpler entering of email addresses. There’s nothing more annoying than visiting a text field that only accepts numbers and being presented with the full QWERTY keyboard minus the digits or needing to enter an email address and having to change key layouts to locate the ‘@’ symbol.

Also, in addition to native OS quirks, a JavaFX app has to be able to communicate with devices such as the camera, GPS, battery etc. or the range of possible mobile apps will be seriously limited. Fortunately JNI/JNA will probably come to the rescue here for any features not accessible from the standard JavaFX/iOS/Android API.

So for this condition to be met, JavaFX apps will have to be as competent at interfacing with the native OS and devices as any true native app.

5. They must be as available as native apps and available from the same channels (e.g. iOS app store)

There’s little point in developing apps for mobiles and tablets using JavaFX if they come with “special” (read irritating) deployment requirements.

Basically, for this condition to be met, JavaFX apps must be available wherever native apps are available and be able to be installed in exactly the same way. This definitely presents some challenges for Oracle given that some of these stores (especially the iOS app store) impose strict conditions on many aspects of the apps submitted for release there. JavaFX apps must (somehow) be free of any limitations imposed “just because they are written in Java”. If they are hobbled in any way, this condition is not met.

6. They must be as easy to update as native apps and through the same channels

This clearly follows on from the previous condition. Once JavaFX apps are installed on mobile and tablet devices, they must be able to be updated in precisely the same manner as true native apps. If any extra or non-standard steps are required to update a JavaFX app then this condition has not been met.

Only when all six conditions have been satisfied will we have a viable port of JavaFX to mobiles and tablets.  Anything less than that is a fail.

I hope Oracle both agrees with me and is taking notice!

Just my 2 bits

Felix

JavaFX Image Pixelator (Using Lambdas)

I wanted to play around a bit with Lambdas in Java 8 and I had a little demo of image pixelation in JavaFX that I based on some code posted by Gerrit Grunwald (@hansolo_) some time ago and decided this was a good place to start!

So for those who don’t like to wait, here’s a little video of the end result:

So what are Lambdas I hear you ask?  Lambdas are basically a more concise way of defining anonymous inner classes which have only a single method and are very common in Java programming (and in many other languages).  Possibly the most familiar anonymous inner class with a single method for Java developers is an implementation of the Runnable interface which has just the one method run().  Swing programmers will have encountered many such classes every time they add a Listener to a Component such as an ActionListener with its method actionPerformed().  Another common form is an implementation of the Comparator interface with the method compare().

In all these cases, the anonymous inner classes are implementing an interface with a single method and these interfaces are known in Java 8 parlance as “functional interfaces” (and known previously as a Single Abstract Method type or SAM).  Lambdas are a very concise way of implementing these functional interfaces.

For the more academic readers, the formal syntax of a Lambda is:

()|x|(x,..,z) -> expression|statement

where x and z are arguments and -> is akin to the “new” operator.  In the expression form, the body is simply evaluated and returned. In the block form, the body is evaluated like a method body and a return statement returns control to the caller of the anonymous method.

Here are some simple examples:

(int x, int y) -> x + y
() -> 42
(String s) -> { System.out.println(s); }

Here’s a more detailed example that compares the anonymous inner class way with the Lambda way and highlights the conciseness of the latter:

public class RunnableTest {
    public static void main(String[] args) {

        // Runnable implemented as anonymous inner class (the old way).
        Runnable r1 = new Runnable() {

            @Override
            public void run() {
               System.out.println("There must be a better way!");
            }
        };

        // Runnable implemented as a Lambda (the new way).
        Runnable r2 = () -> { System.out.println("This is the better way!"); };

        // Running them is identical.
        r1.run();
        r2.run();
    }
}

Let’s have a look at the actual use of Lambdas in the code used in this example.

As with all code I release as part of my blog, this is the “license” I stipulate:

/*
 * This code is completely free of any restrictions on usage.
 *
 * Feel free to study it, modify it, redistribute it and even claim it as
 * your own if you like!
 *
 * Courtesy of Bembrick Software Labs in the interest of promoting JavaFX.
 */

I hope that’s OK with you :-)

First, here I use a Lambda to define a listener on the value property of a JavaFX Slider:

/**
* Creates a <code>Slider</code> to allow manual control over the level of pixelation.
*/
private Slider createSlider(final WritableImage wi) {
    final Slider result = new Slider();
    result.setMin(SLIDER_MIN);
    result.setMax(SLIDER_MAX);
    result.setMajorTickUnit(5);
    result.setShowTickLabels(true);
    result.setShowTickMarks(true);
    result.setSnapToTicks(true);

    // Use lambdas to bind pixelation of the image to a change in the value of the slider.
    result.valueProperty().addListener((observable, oldValue, newValue) -> {
        Pixelator.pixelate(wi, IMAGE, newValue.intValue());
    });

    return result;
}

And here I use a Lambda to define a handler for an action event on a JavaFX Button:

/**
* Creates the <code>Button</code> used to start and pause the animation. The button will
* either start the animation or pause it.
*/
private Button createButton(final Timeline timeline) {
    final Button result = new Button(START_LABEL);

    // Use lambdas to assign the handler for the "action" event.
    result.setOnAction(e -> {
        if (timeline.getStatus() == Animation.Status.RUNNING) {
            timeline.pause();
            result.setText(START_LABEL);
        } else {
            timeline.play();
            result.setText(PAUSE_LABEL);
        }
    });

    return result;
}

As for the JavaFX bits, well the demo includes a simple Stage with a Button, an ImageView and a Slider.  The Slider allows the user to select a level of pixelation which is applied to the image in real-time.  The demo makes use of a Timeline to control an animation that automatically sets the slider’s value, ranging from the minimum value to the maximum value and then back again.  The Button enables the user to either start the animation or pause it.

Here’s the code that creates the Timeline:

/**
* Creates a <code>Timeline</code> to control the animation of pixelation.
* The timeline will oscillate the value of the slider from minimum to maximum
* and back again.
*/
private Timeline createTimeline(final Slider slider) {
    final Timeline result = new Timeline();
    result.setAutoReverse(true);
    result.setCycleCount(Animation.INDEFINITE);
    result.getKeyFrames().addAll(new KeyFrame(Duration.ZERO, new KeyValue(slider.valueProperty(), SLIDER_MIN)),
      new KeyFrame(new Duration(1000), new KeyValue(slider.valueProperty(), SLIDER_MAX)));

    return result;
}

It uses two KeyFrame instances, one with the slider’s value property at the minimum value (at zero duration) and another with this property at the maximum value (at 1000ms duration).  Using this Timeline will therefore cause this property to gradually change from the minimum to the maximum value over the duration of 1000ms (or 1 second).  By setting the auto-reverse property and also the cycle count property to INDEFINITE we get an animation that continually auto-reverses and repeats indefinitely (or at least until it is paused manually).

Note: Gerrit’s original code had the pixelate() method return a Group with a series of Rectangle nodes as its children, one for each pixelated block.  This version has a parameter of type WritableImage which it uses to write each pixel in the image to be displayed in an effort to make it more efficient.  The performance of the algorithm or the PixelWriter itself is not fantastic and if larger images are selected for pixelation then the performance degrades significantly.  I have not investigated this to any great extent although I am sure that an OpenGL or Direct3D shader could accomplish the same task much faster.

In conclusion, this is another example of the capabiltities of JavaFX and when combined with the new language features coming in Java 8 such as Lambdas, we really do have a powerful platform and toolkit for building cross-platform graphics applications.  Why would you use anything else? ;-)

You can try it for yourself with the JavaFX Image Pixelator Using Lambdas Source including the image file used.

Note: You will require Java 8 to run this example.  This example was tested with JDK 8 b106 which is available here.

By the way, the animal in the image is a Spotted Quoll – a small carnivorous marsupial from Australia.  Quolls were once common across the entire Australian continent but have become endangered over recent years due to predation by feral cats and foxes and also habitat destruction.

Please leave feedback to let me know how this example works for you and any other comments you may have!

Just my 2 bits

Felix

JavaFX with Nashorn Canvas example

Following on from my previous examination of the performance and features of JavaFX Canvas and HTML5 Canvas here and inspired by Jim Laskey’s blogs about Nashorn, I decided I would whip-up a quick example of combining JavaFX Canvas and Nashorn based on an existing HTML5 Canvas example.  I recently found a nice little HTML5 Canvas example and that is what I have implemented here in Nashorn.

For those that don’t know, Nashorn is a JavaScript engine that runs on the JVM and is to be included as part of the upcoming Java 8 release.  It will perform far better than the existing major Java-based JavaScript engine Rhino because it utilises the new invokedynamic bytecode added to JDK 8 allowing it to better exploit the power of the JVM.  Nashorn is based on ECMAScript-262 and is fully compliant (which may make it unique in the world of JS engines).

Here’s a short video showing this animation in action:

On my machine, the HTML5 example achieves about 175FPS.  The JavaFX/Nashorn version starts off with a lower framerate but as HotSpot kicks-in over time, this rate increases to almost 200FPS on the same machine.  The framerate that can be seen in the video hovers around 166FPS but this is a symptom of running the video capture software at the same time.

So let’s have a brief look at the code:

var File                 = Java.type("java.io.File");
var Image                = Java.type("javafx.scene.image.Image");
var Color                = Java.type("javafx.scene.paint.Color");
var Canvas               = Java.type("javafx.scene.canvas.Canvas");
var BorderPane           = Java.type("javafx.scene.layout.BorderPane");
var StackPane            = Java.type("javafx.scene.layout.StackPane");
var Scene                = Java.type("javafx.scene.Scene");
var Font                 = Java.type("javafx.scene.text.Font");
var FontSmoothingType    = Java.type("javafx.scene.text.FontSmoothingType");
var Text                 = Java.type("javafx.scene.text.Text");
var AnimationTimer       = Java.type("javafx.animation.AnimationTimer");
var PerformanceTracker   = Java.type("com.sun.javafx.perf.PerformanceTracker");
var AnimationTimerExtend = Java.extend(AnimationTimer);

var WIDTH = 1200;
var HEIGHT = 900;

var canvas = new Canvas(WIDTH, HEIGHT);
var imageUrl = fileToURL("avatar.png");
var img = new Image(imageUrl);
var font = new Font("Arial", 16);
var fpsLabel = new Text();

function renderFrame() {
    var t = new Date().getTime();
    var gc = canvas.graphicsContext2D;

    gc.setFill(Color.web("#cccccc"));
    gc.fillRect(0, 0, WIDTH, HEIGHT);
    gc.setStroke(Color.web("#000000"));

    gc.setLineWidth(1);
    gc.strokeRect(5, 5, WIDTH - 10, HEIGHT - 10);

    var c = 200;
    var msc= 0.5 * HEIGHT / img.height;
    var sp0 = 0.003;
    for (var h = 0; h < c; h++) {
        gc.setTransform(1, 0, 0, 1, 0, 0);
        var yh = h / (c - 1);
        gc.translate((0.5 + Math.sin(t * sp0 + h * 0.1) / 3) * WIDTH, 25 + (HEIGHT * 3 / 4 - 40) * (yh * yh));
        var sc = 30 / img.height + msc * yh * yh;
        gc.rotate(90 * Math.sin(t * sp0 + h * 0.1 + Math.PI));
        gc.scale(sc, sc);
        gc.drawImage(img, -img.width / 2, -img.height / 2);
     }

    gc.setTransform(1, 0, 0, 1, 0, 0);

    fpsLabel.setText(Math.floor(tracker.getAverageFPS() + 0.5) + " FPS");
}

function fileToURL(file) {
    return new File(file).toURI().toURL().toExternalForm();
}

var timer = new AnimationTimerExtend() {
    handle: function handle(now) {
        renderFrame();
    }
};

var stack = new StackPane();
var pane = new BorderPane();
pane.setCenter(canvas);

fpsLabel.setManaged(false);
fpsLabel.setFont(font);
fpsLabel.setFontSmoothingType(FontSmoothingType.LCD);
fpsLabel.setX(10);
fpsLabel.setY(24);

stack.getChildren().add(pane);
stack.getChildren().add(fpsLabel);

$STAGE.scene = new Scene(stack);
var tracker = PerformanceTracker.getSceneTracker($STAGE.scene);

timer.start();

The animation can be launched using the following command:

jjs -fx -Djavafx.animation.fullspeed=true -scripting sprites.js

The command jjs (which you will find in your Java bin directory) is used to launch Nashorn and the -fx argument tells Nashorn that it is to launch a JavaFX application.  The argument -Djavafx.animation.fullspeed=true lets JavaFX run at the maximum framerate it can support.  Without this option, the animation timer will be capped at 60FPS based on the frequency of the “pulse”.

Once again I have found that the performance of JavaFX is at least as good as any HTML5 Canvas implementation and, now with Nashorn, it is even easier to convert web-based animations into JavaFX animations.  Nashorn will bring high-performance JavaScript to the JVM and enable advanced scripting for Java, JavaFX and any JVM-based language applications.

You can try it for yourself with the JavaFX Nashorn Canvas Source including the image file used, the Nashorn script and a BAT file to launch the animation on Windows.

Note: You will require Java 8 to run this example.  This script was tested with JDK 8 b105 which is available here.

Please leave feedback to let me know how this example works for you and any other comments you may have!

Just my 2 bits

Felix

JavaFX Canvas versus HTML5 Canvas

Introduction

In my previous post I stated the evidence for why I consider JavaFX to be a “Golden Goose” for software developers.  Now I’d like to present more evidence as to why JavaFX just rocks.

I will start with the Canvas node.

The JavaFX Canvas is unique in the range of “nodes” supported in the API as it utilises immediate mode as opposed to the retained mode of the other node types.  This means that the programming language itself (i.e. any JVM language such as Java) describes the graphics, text and images and the way they are rendered as opposed to a scene graph.  The rendering happens immediately where as with a scene graph, the definition of the objects to be rendered are retained in memory and then rendered on each pulse.

The concept of a canvas is not new to JavaFX; in fact, the JavaFX version is based on the Canvas element of HTML5 and has a very similar API.  I wanted to determine just how the JavaFX implementation stacks up to the HTML5 version so I devised a simple particle-style demo which renders each particle as either simple graphics (a ball), as text or as an image and then compared the demo running in JavaFX and HTML5.

I have read many times that the JavaFX Canvas is supposed to out perform the HTML5 Canvas so I wanted to find out for myself if this was accurate or just hype.

For those who can’t wait for an analysis of the results, here is a short demo highlighting the differences.  It is worth noting that for both JavaFX and HTML5, the animations when observed in “real life” are much smoother than they appear in the captured video.

It is clear from the video that JavaFX out-performs HTML5 in all particle styles and for the text particle it absolutely blows HTML5 away!

Let’s dig a little deeper…

Comparison of the APIs

As I mentioned, the APIs of the JavaFX Canvas and HTML5 Canvas are very similar.  Both include methods to stroke and fill graphics primitives such as arcs, curves (Bezier & quadratic), lines, rectangles and text as well as drawing images, applying transforms and clipping along with saving and restoring state.

As similar as they are, the following is a summary of some of the differences between the two Canvas implementations:

  • HTML5 Canvas has no explicit methods to fill ovals or polygons
  • JavaFX Canvas has the cool appendSVGPath() method which adds a “path” as used in SVG to the current path
  • HTML5 Canvas has no explicit method to apply an effect (such as a blur etc.)
  • HTML5 Canvas has an extra method isPointInStroke() which is not in JavaFX Canvas (although both support isPointInPath())
  • Some methods (such as arc()) have different parameter lists

There are probably other differences but all-in-all, it’s really very simple to convert your code between JavaFX Canvas and HTML5 Canvas.

Performance

All demos were run on the same machine and OS whose specifications are:

  • Hardware: Dell Precision T7500 Workstation
  • CPU: 2 x Intel Xeon W5590 3.3GHz
  • RAM: 24GB
  • GPU: NVIDIA QuadroFX 5800
  • OS: Windows 7 Ultimate 64-bit SP1
  • JDK: Java 7 Update 25 64-bit
  • Browser: Chrome 28.0.1500.95 m

Note: No thorough quantitative analysis of the performance characteristics was done so I am relying entirely on my observations.  In terms of “performance”, I am referring to the speed of the animations and also their smoothness.

The most obvious conclusion from running the demos and several variations including number of particles and complexity of graphics is that JavaFX really does perform extremely well.  There was never any demo configuration that performed better in HTML5 than it did in JavaFX.  In fact, the text particle demo runs so much slower in HTML5 that I had to limit the time in the video allocated for that demo.

Further, I was able to increase the number of particles in the JavaFX demos to almost ridiculous levels and they still performed well.  In contrast, I wasn’t able to increase the number of particles in the HTML5 demos much beyond a few thousand before the speed and smoothness of the animations degraded significantly.

I encourage you to try out the code below and fiddle around with all attributes of the demos and then report back here with your results.

HTML5 Canvas ain’t HTML5 Canvas!

One of the most important discoveries from these tests was that the performance characteristics of the “standard” HTML5 Canvas element are very different in different browsers.  I tested the demos with Chrome 28, Firefox 22, IE 8 and IE 10.  Overall Chrome performed the best but, as I said, it seems to have major performance issues with text rendering.  Firefox text rendering was much better but the image demo simply didn’t work at all.  IE 10 did surprisingly well with all the demos but IE 8?  Well, just forget it!

This pretty much destroys the argument that is frequently brought up by HTML5 fanboys that HTML5 is a “standard” platform across many devices and operating systems.  While it’s true that the API itself is the same, it is disturbing that my HTML5 app is going to behave quite differently depending on the browser that the end-user is running at the time.  Given that this is usually the primary argument for using HTML5, it’s just another tick in the JavaFX box.

As an aside, the method I used to blur the HTML5 canvas (by setting canvas.style.webkitFilter) only worked in Chrome but given that Chrome is the only WebKit based browser I tested I guess that’s not entirely surprising and I am sure there must be other ways of achieving this effect anyway.

Conclusion

It is patently obvious that JavaFX is more than capable of highly performant animations and in all the tests I have conducted personally, it out-performs its HTML5 cousin, sometimes quite dramatically.  This is another reason why I believe JavaFX is emerging as the best graphics toolkit for developing rich front-end applications on the market today.  Given these performance characteristics and all the other advantages that it provides (especially all those inherent in using the Java platform itself), I am convinced that JavaFX is here to stay and that it will play an ever-growing role in the future of software development.

As I stated in my previous post, JavaFX does not attempt to replace HTML5; both technologies can and will co-exist, each with their own strengths and weaknesses and each filling a different niche in the software ecosystem.

Try It Yourself

You can download all of the source files for these demos (including Java, HTML and the images used) and try them out for yourself.

Note: As anyone who has worked with me will attest, my code is usually erring on the side of “over commenting” rather than “under commenting” and while experienced software developers may consider this noise, I have found that such comments are invaluable for those starting out with a new language or technology.

Download the source here JavaFX Canvas versus HTML5 Canvas Source and give it a bash!  Please leave comments below and let me know how these demos work in  your environment and any other feedback on this topic.

Just my 2 bits

Felix

JavaFX: Lame Duck or Golden Goose?

The software industry is highly competitive and just like consumers, developers have to wade through a sea of FUD and misinformation when it comes to selecting the languages and tools for their next project.

This is particularly true for JavaFX.

Consider the following much-uttered statements:

  • Rich client and/or the desktop is dead.
  • The web browser is the platform of the future.
  • HTML5 and JavaScript are the only languages you need to learn.
  • HTML5 applications are just like native applications.
  • HTML5 is the only true cross-platform technology.
  • Java will never run on mobiles or tablets.
  • Java is dead.
  • JavaFX is D.O.A.

I for one am sick and tired of guff like this because all of it is in fact completely incorrect.

For example, despite an enormous amount of hype, HTML5 is not going to cure cancer or put a man on Mars or do whatever the current outlandish claim about this technology is.  HTML5 is very important and has a very significant role to play in the future of software development but if you believed everything you read on the interwebs about it you might as well ditch all other languages and devote your life to the worship of everything HTML5.

Well, don’t.

If your requirements are for modern web sites then by all means invest in learning HTML5, CSS3 and, of course, JavaScript.  But that’s just it: HTML was and is designed for web sites, not applications, despite what HTML5 fanboys might tell you.  Even with all the (excellent) improvements in HTML5 that were not present in its predecessors, you still have a platform that is most suitable for presenting pages of marked-up text with hyperlinks, media and graphics.  The key word here is “page” which is a vastly different animal from an “application”.

It’s true that HTML5 allows you to build “things” that can be accessed on all the major classes of devices we currently use but these “things” will always be web sites and not what end users have come to know as “applications”.  This is because web sites have serious limitations that prevent them morphing into fully fledged applications such as performance limitations, lack of support for multi-threading, poor access to native APIs, lack of advanced programming language features such as true OOP, poor access to hardware devices/sensors etc. and a very limited range of APIs to make use of in the first place.  For these reasons there are many software categories that are simply not suitable for web-based deployment.  For such software we need the power of native applications.

Consider this tidbit: when iOS was first released, Apple actually expected developers to favour web-based software over native applications.  Not only did developers not want this but consumers were never going to be satisfied with the sub-standard apps that resulted from using the web technologies available at the time and now, years later and even with the release of improvements to HTML5, the vast majority of software used on iPhones and iPads is delivered as native apps.  The Android experience is much the same.  Even with Microsoft’s “Modern UI” found in Windows 8 and Windows RT that tried to promote HTML5/JavaScript development, native apps dominate.

Clearly then, not only are native apps alive and well but they still have an enormous part to play in the future of software development.  What definitely isn’t FUD or misinformation is the *fact* that HTML applications (i.e. web sites) and native apps can and will live side-by-side for many years to come simply because they fill very different niches.  And quite clearly neither rich client nor the desktop are anywhere near death.  The reality is starkly different with desktop applications surviving into the future for at least 15 years as there remain several niches where only such applications can deliver.

Accordingly I’d like to now focus on native apps and the various ways they can be developed and deployed.  If you are only interested in HTML5 then GIYF and, you are seriously missing out.

Up to this point I have been using the terms “app” and “application” somewhat interchangeably.  The distinction between the two has probably never formally been defined but I suppose most people think of applications as software that runs on a desktop and apps as software that runs on a mobile phone or tablet device.  As far as I am concerned, these is actually no distinction between these two terms and I will now focus on using the word “app” simply because it requires fewer letters to type.

So, I have a great idea for a new app, now I have to ask myself some key questions:

  1. What language(s) and tool(s) am I going to use to develop it?
  2. Which platforms is it going to be deployed to?
  3. How can I minimise the effort and costs involved in development yet maximise its global presence?

Well, there are two main approaches to development of “native” apps that are used today namely finding some kind of cross-device meta platform or language that will enable me to develop using a core code base and deploy to a number of devices with minimal changes or utilising the best languages and tools on each device/platform to maximise the “native” experience but pay the cost of having to write large chunks of platform-specific code.

Choosing between these two approaches has never been easy and usually comes down to being determined by the specific nature of the app or even personal experience or choice.

I don’t know about you but I certainly don’t have the time or financial resources to build software specific to each particular platform even if I am able to compartmentalise as much core code as possible that can be reused.  It’s not just the development effort but testing on multiple devices and platforms is extremely time-consuming.

So that’s one of the reasons why I am looking at JavaFX.

For those that don’t know, JavaFX is the new(ish) graphics toolkit for Java applications that has officially replaced the now deprecated Swing toolkit.  It’s strengths are that it is high-performance (being hardware accelerated), supports 2D & 3D graphics and animations, does charting, plays media, includes a WebKit based browser component, has sophisticated data binding capabilities and utilises an XML-based file format known as FXML.  There is also a drag-and-drop WYSIWYG design tool known as Scene Builder for whipping-up GUIs fast.  And JavaFX is open source.  Further, JavaFX apps run on almost every operating system known to mankind…

…or almost.  The major caveat is that currently there is no “official” release of JavaFX for iOS or Android.  There isn’t one for Windows Phone either but that is hardly a weakness :-) However, members of the JavaFX community have demonstrated working examples of JavaFX running on iOS and Android using a product called RoboVM.  Given that these demos prove that there is only a lack of investment getting in the way, I believe it is only a matter of time before we will see apps written in JavaFX in the Apple App Store and in Google Play.

When I say “JavaFX” I am not referring to the first generation JavaFX that was released in about 2007.  That JavaFX was a different beast because it relied on a brand new scripting language called JavaFX Script and basically very few people bothered to learn it.  It wasn’t that the language was bad (in fact it had some outstanding features); it’s just that Java programmers wanted to keep programming in Java.  And now they can.  With the advent of JavaFX 2, the API is just-another-Java-API and the JavaFX functionality can be accessed from any JVM-based language such as Groovy or Scala.  This is a *huge* advantage over JavaFX 1 and is the main reason why interest in JavaFX has exploded in the last couple of years.

A very broad range of apps can be developed using JavaFX ranging from simple form-based UIs to complex 2D/3D graphics incorporating audio and video playback and animated content.  It is therefore suitable for business apps and games as well.  Sure, I wouldn’t choose JavaFX to write Halo 6 or build an operating system but they’re not the kind of apps I develop on a daily basis and I don’t think many people actually get to work on such projects very often.  But for your most common business and personal software requirements, JavaFX is an ideal fit and not just for Java programmers.  While it is very clear that Java programmers will be by far the most abundant users of JavaFX, developers who have never used Java will gravitate to this toolkit because it offers them features, performance levels and deployment options not readily available with other products.

Also, there is a real buzz about JavaFX in the Java community at the moment with several high-profile JavaFX rock stars motivating people like me to get involved.  If you have questions, someone will quickly respond on the official JavaFX forum and more and more code snippets are cropping up online to help you bash out your first app.

I have to say that having considered all the options I could locate and after a great deal of research and actual software testing I am convinced that JavaFX is no Lame Duck.  Quite the contrary in fact.  It’s a Goose; a Goose of the Golden variety.

Just my 2 bits.

Felix

Follow

Get every new post delivered to your Inbox.

Join 141 other followers

%d bloggers like this: