JavaFX using Kawa - introduction
JavaFX 1.0 was a next-generation GUI/client platform. It had a new Node-based GUI API and used a new language, JavaFX Script, whose goal was to make it easier to program Rich Client applications. (Yours truly was hired by Sun to work on the JavaFX Script compiler.) In 2010 the JavaFX Script language was cancelled: JavaFX would still refer to a new GUI based API based on many of the same concepts, but the primary programming language would be Java, rather than JavaFX Script.
Java is a relatively low-level and clumsy language for writing Rich Client appliations, though it's not too painful. Still, there was a reason we worked on JavaFX Script: It had a number of features to make such programs more convenient. Luckily, other JVM languages - and specifically Kawa-Scheme - can take up the slack. Below I'll show you a simple Hello-World-type example, and then explain how you can try it yourself. In later acticles I'll show different examples.
Simple buttons and events
Our first example is just 3 buttons and 2 trivial event handlers. It is translated from HelloButton.java written in Java by Richard Bair.
(require 'javafx-defs) (javafx-application) (javafx-scene title: "Hello Button" width: 600 height: 450 (Button text: "Click Me" layout-x: 25 layout-y: 40 on-action: (lambda (e) (format #t "Event: ~s~%" e)) on-key-released: (lambda (e) (format #t "Event: ~s~%" e))) (Button text: "Click Me Too" layout-x: 25 layout-y: 70) (Button text: "Click Me Three" layout-x: 25 layout-y: 100))
For those new to Scheme, the basic syntactic building block has the form:
(operator argument1 ... argumentN)The
operatorcan be a function (like
format), an arithmetic operator in prefix form (like
(+ 3 4)), a command, a keyword (like
lambda), or a user-defined macro. This general format makes for a lot of flexibility.
The first two lines in
HelloButton.scm are boiler-plate:
require imports various definitions and aliases,
(javafx-application) syntax declares
this module is a JavaFX
javafx-scene form (a macro) creates a scene,
which is a collection of graphical objects.
Scene has certain named properties (
height), specified using keyword arguments. The
Scene also has 3
make-scene command puts the scene
on the stage (the window) and makes it visible.
Button form is an object constructor. For example:
(Button text: "Click Me Three" layout-x: 25 layout-y: 100)is equivalent to the Java code:
javafx.scene.control.Button tmp = new javafx.scene.control.Button(); tmp.setText("Click Me Three"); tmp.setLayoutX(25); tmp.setLayoutY(100); return tmp;
properties on the first
Button bind event handlers.
Each handler is a lambda expression or anonymous function that takes an event
e as a parameter. The Kawa compiler converts the handler to a suitable
event handler object using
(This conversion depends on the context, so if you don't have a
literal lambda expression you have to do the conversion by hand
Getting it to run
Downloading JavaFX 2.x beta
For now JavaFX is only available for Windows, but Mac and GNU/Linux ports are being worked on and mostly work. (I primarily use Fedora Linux.) The primary JavaFX site has lots of information, including a link to the download site. You will need to register, as long the software is beta. Download the zipfile and extract it to some suitable location.
In the following, we assume the variable
is set to the build you've installed. For example (if using plain Windows):
set JAVAFX_HOME=c:\javafx-sdk2.0-betaThe file
Downloading and building Kawa
The JavaFX support in Kawa is new and experimental (and unstable), so for now you will have to get the Kawa source code from SVN.
There are two ways to build Kawa. The easiest is to use Ant - on plain Windows do:
ant -Djavafx.home=%JAVAFX_HOME%or on other platforms (including Cygwin):
Alternatively, you can use
(but note that on Windows you will need to have Cygwin installed to use this approach):
$ KAWA_DIR=path_to_Kawa_sources $ cd $KAWA_DIR $ ./configure --with-javafx=$JAVAFX_HOME $ make
Running the example
On Windows, the easiest way to run the example is to use the
kawa.bat created when building Kawa. It sets up
the necessary paths for you.
On Cygwin (or Unix/Linux) you can use the similar
I suggest setting your
PATH to find
kawa.sh, so you can just do:
kawa command is equivalent to
java -classpath classpath kawa.repl HelloButton.scmbut it sets the classpath automatically. If you do it by hand you need to include
This is what pops up:
If you click the first button the
action event fires, and
you should see something like:
If you type a key (say
n) while that button
has focus (e.g. after clicking it),
then when you release the key a
key-released event fires:
Event: KeyEvent [source = Button@3a5794[styleClass=button], target = Button@3a5794[styleClass=button], eventType = KEY_RELEASED, consumed = false, character = , text = n, code = N]
Note: Running a JavaFX application from the Kawa read-eval-print-loop (REPL) doesn't work very well at this point, but I'm exploring ideas to make it useful.
Compiling the example
You can compile
HelloButton.scm to class files:
kawa --main -C HelloButton.scm
You can execute the resulting application in the usual way:
java -classpath classpath HelloButtonor use the