JavaScript is everywhere these days and so it is also part of JDK8 dev. prev. with Project Nashorn which is a lightweight high-performance JavaScript runtime engine.

Because I never used Rhino (which is in principle the same just older and slower) I had no idea how to use it and for what reason.

After I met Marcus Lagergren (@lagergren) at JAX in Mainz (Germany), Geecon in Krakow (Poland) and at Java Forum in Malmö (Sweden) I decided that I have to take a look at the Nashorn to get an idea on how to use it. Of course I'm especially interested on how to use Nashorn in combination with JavaFX. Lucky me that Nashorn is part of the weekly developer previews of JDK8 since a few weeks ago and because Jim Laskey (@wickund) blogged about this use case I was able to start with it yesterday.

After some starting problems I slowly begin to understand and would like to share it with you...

First of all I would like to see how I could use Nashorn with JavaScript in combination with my controls, so the idea is to visualize a Lcd control of my Enzo library with Nashorn.

For the following example you'll need the jdk8 developer preview (grab it here) and a current version of my Enzo library (grab it here).

And with a shell and a text editor you are good to go...really nice :)

So first of all we need to create a JavaScript file that should create a JavaFX application which should show the Lcd control and set's the value of the Lcd control every 3 seconds to a random value between 0 and 100.

This is the JavaFX code to realize that...

import eu.hansolo.enzo.lcd.Lcd;

import eu.hansolo.enzo.lcd.LcdBuilder;

import javafx.animation.AnimationTimer;

import javafx.application.Application;

import javafx.geometry.Insets;

import javafx.scene.Scene;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;

import java.util.Random;

public class EnzoFX extends Application {

private Lcd lcd;

private Random random;

privatelong lastTimerCall;

private double charge;

private AnimationTimer timer;

@Overridepublic void init() {

// Initialize the AnimationTimer

random = new Random();

lastTimerCall = System.nanoTime();

charge = 0;

timer = new AnimationTimer() {

@Overridepublic void handle(long now) {

if (now > lastTimerCall + 3_000_000_000l) {

lcd.setValue(random.nextDouble() * 100);

lcd.setTrend(Lcd.Trend.values()[random.nextInt(5)]);

charge += 0.02;

if (charge > 1.0) charge = 0.0;

lcd.setBatteryCharge(charge);

lastTimerCall = now;

System.out.println(lcd.getValue());

}

}

};

// Initialize the Enzo Lcd control

lcd = LcdBuilder.create()

.styleClass(Lcd.STYLE_CLASS_STANDARD_GREEN)

.title("Room Temp")

.unit("°C")

.decimals(2)

.minMeasuredValueDecimals(2)

.maxMeasuredValueDecimals(2)

.unitVisible(true)

.batteryVisible(true)

.alarmVisible(true)

.minMeasuredValueVisible(true)

.maxMeasuredValueVisible(true)

.lowerRightTextVisible(true)

.formerValueVisible(true)

.trendVisible(true)

.lowerRightText("Info")

.valueAnimationEnabled(true)

.foregroundShadowVisible(true)

.crystalOverlayVisible(true)

.build();

}

@Overridepublic void start(Stage stage) {

// Prepare stage and add controls

StackPane root = new StackPane();

root.setPadding(new Insets(10, 10, 10, 10));

root.getChildren().add(lcd);

stage.setTitle("Enzo in JavaFX");

stage.setScene(new Scene(root, 528, 192));

stage.show();

// Start the timer

timer.start();

}

public static void main(String[] args) {

launch(args);

}

}

Ok, so now we know how to achieve this in JavaFX but now let's take a look at the JavaScript code that leads to the same result. Here you go...

var System = java.lang.System;

var Random = java.util.Random;

var StackPane = javafx.scene.layout.StackPane;

var Scene = javafx.scene.Scene;

var Insets = javafx.geometry.Insets;

var AnimationTimer = javafx.animation.AnimationTimer;

var Lcd = Packages.eu.hansolo.enzo.lcd.Lcd;

// Initialize the AnimationTimer

var random = new Random();

var lastTimerCall = System.nanoTime();

var charge = 0;

var timer = new AnimationTimer() {

handle: function(now) {

if (now > lastTimerCall + 3000000000) {

lcd.value = random.nextDouble() * 100;

lcd.trend = Lcd.Trend.values()[random.nextInt(5)];

charge += 0.02;

if (charge > 1.0) charge = 0.0;

lcd.batteryCharge = charge;

lastTimerCall = now;

print(lcd.value);

}

}

}

// Initialize the Enzo Lcd control

var lcd = new Lcd();

lcd.styleClass.add(Lcd.STYLE_CLASS_STANDARD_GREEN);

lcd.title = "Room Temp";

lcd.unit = "°C";

lcd.decimals = 2;

lcd.minMeasuredValueDecimals = 2;

lcd.maxMeasuredValueDecimals = 2;

lcd.unitVisible = true;

lcd.batteryVisible = true;

lcd.alarmVisible = true;

lcd.minMeasuredValueVisible = true;

lcd.maxMeasuredValueVisible = true;

lcd.lowerRightTextVisible = true;

lcd.formerValueVisible = true;

lcd.trendVisible = true;

lcd.lowerRightText = "Info";

lcd.valueAnimationEnabled = true;

lcd.foregroundShadowVisible = true;

lcd.crystalOverlayVisible = true;

// Prepare the stage and add controls

var root = new StackPane();

root.padding = new Insets(10, 10, 10, 10);

root.children.add(lcd);

$STAGE.title = "Enzo with Nashorn";

$STAGE.scene = new Scene(root, 528, 192);

$STAGE.show();

// Start the timer

timer.start();

The JavaScript code that I saved to a file "javafx.js" looks not that different from the JavaFX code except...it's JavaScript...and the resulting application will look like this...

You might ask yourself how you could run this code and here is the answer, all it takes is one call on the command line that looks like this:

Means you have to now the path to your jdk8 installation folder where you could find the jjs executable that is needed to start nashorn from the command line. In addition you have to add the Enzo.jar to the classpath so that you could use it within your JavaScript file and at last you have to call the JavaScript file with the -fx parameter which will start the application....BAM...that's all...sweet :)

I've put the commandline in a bash script so that I could call it by simple calling the bash script instead of typing the whole line over and over again.

If you start the javafx.js file you should see something like on this youtube video.

Ok you might say where is the advantage of using JavaScript to run a JavaFX application...just think about not starting an IDE, not compiling and building a JavaFX application just to make a short test. Isn't it be much nicer to simply have a small JavaScript, edit it with your default text editor and run it with from the command line with one single call...I really like that for testing things.

Tuesday May 07, 2013

So after some playing around and working with the JavaFX folks, I think we have a proposal for jjs that works with JavaFX. The -fx flag on jjs will bootstrap scripts using a javafx.application.Application. Thus, writing JavaFX scripts in Nashorn is very easy.

The basic command line is;

jjs -fx fxscript.js

You can mix and match other jjs options like -scripting and -- ;

jjs -fx -scripting fxscript.js -- my script args

The content of the script follows some of the examples I've posted before. The script may optionally contain JavaFX init, start and/or stop functions. What is new, is that you can leave them behind and just straight script. The original hello world example;

where the stage is now a global var $STAGE (instead of the start function argument.)

Also for convenience, we've predefined includes for all of the JavaFX classes. I would recommend using only the classes you need (only needed for new and for static field access), but for prototyping having includes really helps things move along.

Node.js is hot and anyone who has used it knows there is a ton of applications possible. Some of Node.js features remind me of a tool kit I had, when I worked for another server company prior to Oracle. All my development was remote and had to run on remote servers. I hate typing and ssh/console was my only way in. So, I decided that I would create a little HTTP server on the remote end, to proxy all my routine repository, build and file editing tasks via a browser. This didn't take a lot of effort and was very flexible.

There are many many HTTP server apps out there (many written in Java.) I could modify one of them, but I just wanted to prove to myself it could all be done in pure Nashorn. This is what I whipped up;

Note that both the JavaScript and HTML content of the .jjsp file is very easy to read. This particular script catalogs a directory (ls) and colourizes the result depending on the file extension. In my case the result was;