Featured Post

Return of the prodigal son

I'm a man and as a man I sin. My eval doings have come back to me making me miserable and little man. I spent those two months on meditation and repentance. I swore to my self that I'll relinquish of all eval and I'll walk on the path of truth.

Read More

Clojure with JavaFx 2.0

Posted by Emil Kruczek | Posted in Coding | Posted on 07-06-2011

3

Oracle finally released beta version of JavaFx 2.0 which can be found here. I’ve downloaded SDK and Runtime as soon as I’ve been able to create an account at Oracle site. My first impression of JavaFx 2.0 Beta is quite good, although I’m little bit disappointed about lack of support for other operating systems. Now some of you think “Get to the main point buddy”, ok here is my way of getting leiningen clojure and javafx to work together.

First of all download JavaFx SDK and Runtime environment for your architecture. It’s important to download files for correct architecture because files for x86 files don’t work on x64 machine. Having downloaded Runtime environment install it and extract downloaded sdk to some place on the disk.

I assume that you know how to install leiningen on Windows and you know how to use it. If you don’t have any knowledge of this tool leiningen readme at github is a good place to start.
Lets create new project simpleapp:

lein new simpleapp

JavaFx application uses some kind of “launcher” which determines path of JavaFx Runtime Environment installed on machine and runs app in that environment. Because of that we need to embed this launcher in our application. Lets begin

  1. Crate folder called resources under your project root folder
  2. Unzip (with 7z or another utility)  file uncompresed_javafx_sdktoolsant-javafx.jar
  3. Copy directory uncompreser_javafx_sdktoolsant-javafxresourcesclassescom to your_projectresources
    (comjavafxmainMain.class is mentioned earlier “launcher”)

Because JavaFx doesn’t install were Java does we need to extend classpath which leiningen uses to compile clojure files, if not all code importing and using JavaFx classes won’t compile. First off all find out where JavaFx Runtime Environment is installed (for me that was C:Program Files (x86)OracleJavaFX Runtime 2.0. In this folder are folders lib and bin. lib contains jar packages needed to compile and run our application, and bin contains native libraries used to do things on Windows operating system. To extend classpath I’ve used solution provided by Christopher Lin

  1. Create folder hooks under your project root directory.
  2. Create file classpath.clj in the hooks directory

File hooks/classpath.clj should contain:

(require 'robert.hooke)
(require 'leiningen.classpath)

(robert.hooke/add-hook #'leiningen.classpath/get-classpath
                       (fn [get-classpath project]
                         (conj (get-classpath project)
                "Path_to_Runtime_Environment\lib\jfxrt.jar")))

Above code changes leniningen.classpath/get-classpath function so that it returns value of path to jfxrt.jar and value of itself.

Now we need to edit project.clj to include hooks, set “launcher” as main class and tell “launcher” which class to launch

(defproject simpleapp "1.0.0-SNAPSHOT"
  :hooks [hooks.classpath]
  :aot [pl.altasoft.simpleapp pl.altasoft.core]
  :resources-path "resources"
  :description "FIXME: write description"
  :manifest {"JavaFX-Application-Class" "pl.altasoft.core"
             "JavaFX-Version" "2.0"
             "Main-Class" "com/javafx/main/Main"}
  :dependencies [[org.clojure/clojure "1.2.1"]]
  :dev-dependencies [[swank-clojure "1.3.1"]])

Keyword :hooks tells what hooks file to load. We tell leiningen to copy resources from resources directory via :resources-path keyword.
We also need to change generated manifest. Now Main-Class has value of "com/javafx/main/Main" which is “launcher” and "JavaFX-Application-Class" tells “launcher” which class should it run.
Important don’t use :main keyword because it overrides Main-Class entry in :manifest map!!!

That’s the fundamentals that need to be done to start writing JavaFx applications in clojure.
Hope this can help somebody.

In next post I’ll show how to write simple JavaFx application in clojure.

Comments (3)

Re: adding jfxrt.jar to the build classpath, why not just make that jar available as a regular dependency? Whether you just install the jar in your local Maven repository, in a repository server (like Nexus or Artifactory), or use github as a Maven repository, you’d be able to skip the use of robert hooke, avoid the manual download and unzipping, etc.

Doing one of the above is a must for using dependencies that are not available in a Maven repo. (The fact that the beta release isn’t in Maven central — or at least the java.net repo — is silly and counterproductive, but that’s another topic. :-)

Because jfxrt.jar needs native .dll’s (or .so files for linux) specific for os on which application will be run. You want to use libraries (JavaFx runtime) which are installed on target machine, so you don’t ship them with your app. I think that with future releases of JavaFx, jfxrt.jar will be in standard java classpath so robert hooke will not be needed.

entertaining article Cheers again