Friday, January 25, 2013

How to create 2D Lightning Effects - with JavaFX

This time I invite you to follow my path to another nice 2D effect: Lightning.

Election night crowd, Wellington, 1931
Election night crowd, Wellington, 1931 

Friday evening, surfing. Then, suddenly I was struck by lightning. Here.

This blog post is about my journey to a decent looking lighning bolt visualisation using Scala and JavaFX.

As a side note: I really appreciate Oracles move to support JavaFX with plain Java, and thus opening up the API for all JVM based languages, otherwise the following approach would never have been possible.

So let's start:

Level -1: Create a glowing line


Well, that should be easy with JavaFX. What do we need? Just a Line and an effect? Maybe even a premade effect which is named Glow? And a Line? Well. Almost:



This gives me a picture like this:

A glowing line (sort of)

Ok, seems ok for me. Lets proceed to

Level 0: Create jagged lines


My lightning is so far only a straight line, but I want to have a cool lightning strike. The tutorial I'm trying to reimplement here proposes to partition the line in smaller pieces of a random number. Furthermore it says the endpoints of those lines should be connected and be placed normal to the direction of the original line.

So this is what I came up with:



it will output pictures like this:


This took me some time to figure out - I reinvented the 2D math for myself again, I'm sure this can be done way better. What I'm fond of is how the list of endpoints of the different line sections is traversed - have a look!

Level 1: Animation


What I would like to see is some interaction. Clicking somewhere in the canvas and then - BANG! - the lightning strikes.

What I need to do for that is just use the mouse coordinates, give the canvas a listener for it and thats all since JavaFX handles the erasing of the blurry pixels. Maybe I'll add some flickering to it, some fade outs? More glowing?

For most of my wishes there are already API's for it in the standard library, for example the very handy FadeTransition which I wanted to invent but it was already there ;-).  Have a look at this code snippet:

Fade Transitions are here, for free.
On the otther hand, I definitely wanted also to have some sound effect, which is also a one liner:



Here is the result so far:




The code for the video above is available here.

Level 2: Better layout algorithm for lightning bolts


The next step would be to improve the layout of bolts, add branches and refine the layout algorithm which is at the moment very basic to get a better visual result and to let the bolts look more "natural".

Apart from the link mentioned above, there are also other sources of information available how to generate decent looking lightning bolts. My current approach just places a list of points randomly round a normal line, but a visually more appealing result is possible for example by using the technique of "midpoint replacement". The idea is that you recursively part up a line in two halves, and move the midpoint a random amount of pixels normal to the given direction. With every nested level you may lower the amount of displacement.

So, the relevant code would look like this (inspired by Mr. KrazyDad):


With this new layoutalgorithm, the lightning bolts look much better (and also more like the ones at gamedevtut's site):



You can see the source here. Since I strive to be a well behaved functional programmer I had to swap only one function to achieve this. (My favorite joke: "Two pure functions walk in a bar. Nothing happens.")


Level 3: Branching


At the moment I support painting only one lightning, I want to have some sort of branching so that I get an even better result. This can be accomplished by randomly choosing a subelement of the main thunderbolt, then calculate a new endpoint which points at another direction, and do this again recursively (maybe at a random rate).

Branching adds much value without much pain to our lightning.  I changed the datastructures a little, now I'm saving tuples of start and endpoints in the list which I'm sending to the mkLine function - this simplifies the painting loop considerably (no more sliding windows anymore :( )

Here is the lightning with branches (and different colors):




Level 4: Adding a nice headline

I have added now some text, using a custom font:

Lightning bolts around a headline

Using true type fonts is no problem either when using JavaFX.

Level 5: Put it all together


We have all what we need for our final step - create lightnings to write something on the screen. In order to achieve this effect, we need to write the headline into a WriteableImage and use the rasterized information for source and endpoints of randomly generated bolts. By using a simple trick which prefers two points which are nearer to each other than two points with a longer distance, we achieve a nice looking effect you may have once or twice seen in games or other visual effects.

This whole application is by no means optimized, you will hear your fan soon when starting the program, but it is no wonder since we are calculating lots of stuff and are generating huge number of nodes.

Have a look at the final result of the 2D JavaFX Lightning blog post, and thanks for reading!




If you want to have a peek at the source code for the whole project, its on github

Monday, January 21, 2013

Calling Ant from Maven using a property file

Consolidating builds for several projects can be a process which sometimes needs some creativity combining the tools already available.

Most of the time it is too risky and expensive to write everything from scratch - even if it is very tempting to do so. In case of Maven and Ant, there is the well known antrun-plugin which makes it possible to integrate Ant based builds into the Maven ecosystem. 

Below is an example how to call Ant from Maven using a property file to store values which may change often.

Maybe somebody finds it useful.

Sunday, January 20, 2013

Native Drag & Drop with JavaFX

Usability is king. Enable your applications with drag and drop support to make your users happy.



JavaFX supports Drag and Drop - I've added some rudimentary DnD support for the tree visualisation program. The code for the whole project is available at github.

The relevant code parts are those here:

basic Drag and Drop Support with JavaFX 

I use the ShapeConverter class to convert the javafx based trees to a svg format - you'll find more valuable gadgets like this in the jfxtras project.

On MacOsX this code can drop directly into the browser, but not on the desktop for example. Under Windows7 it works however. Have a look at the jira for a list of open DnD JavaFX issues. (login required)

This is just a starting point for drag and drop, you can register even more listeners to make your application more user friendly - see the tutorial here.

Friday, January 18, 2013

ScalaFX - A DSL for JavaFX in Scala

ScalaFX is an opensource project which aims to provide a concise DSL for using JavaFX with Scala.


Scientific apparatus, 1939, 1
Scientific apparatus, 1939, 1


Only very recently the ScalaFX project was restructured and it is now easier to set it up and build it - Peter Pilgrim did a great job setting up the sbt build. I want to describe what is necessary to get a maven project running which uses the ScalaFX project.

7 Steps to a running ScalaFX application with maven


(If you have tried out examples of this blog you may have installed the prerequisites already, so you can skip until step 1.):


-4) Make sure maven is installed:

Get it at here.

-3) Install Mercurial: 

Get it here.

-2) Make sure you are using a recent JDK (1.7.11 or newer):

Get it here.

-1) Install the simple build tool for scala

Get it here.

0) Execute following command and say "Y"

mvn com.zenjava:javafx-maven-plugin:1.3:fix-classpath

Ok, now you should be set up. Now the ScalaFX specific steps start.

1.) Check out the ScalaFX source code

hg clone https://code.google.com/p/scalafx/

2.) Install it into your local maven repository

In short:

sbt clean compile package make-pom package-src make-pom

mvn install:install-file -DartifactId=scalafx_2.9.2 \
    -DgroupId=org.scalafx \
    -Dpackaging=jar \
    -DpomFile=scalafx-core/target/scala-2.9.2/scalafx-core_2.9.2-1.0-SNAPSHOT.pom \
    -Dfile=scalafx-core/target/scala-2.9.2/scalafx-core_2.9.2-1.0-SNAPSHOT.jar \
    -Dversion=1.0-SNAPSHOT \
    -Dsources=scalafx-core/target/scala-2.9.2/scalafx-core_2.9.2-1.0-SNAPSHOT-sources.jar


will place a maven artifact in your local repository and suddenly you are ready to start coding with ScalaFX. (Skipping tests is of course bad and ugly ;-) )

You have to reference it from any maven project via

<dependency>
<groupId>org.scalafx</groupId>
<artifactId>scalafx_2.10</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>


3) Final step: Clone example project


Anyhow, after going through all this you can clone the scalafx-example project from github. It contains a ScalaFX program which looks like this:

ScalaFX DSL


You can import the project into Eclipse via "Import maven projects" or compile it on the command line via

mvn clean package

Entering

java -jar target/scalafx-example-1.0-SNAPSHOT-jfx.jar 

will show you the following:


ScalaFX HelloWorld

For more information about ScalaFX,  go to ScalaFX.org.

Sunday, January 13, 2013

JavaFX Tree Visualization Part 2

In this blog post I'll post a follow up on my post about painting random generated trees.

My intention was first to improve the code a bit and use a more functional way to express the recursion, now I'm using case classes and more pattern matching to build up the tree. I think now it is far more understandable what is going on.



Moreover I've added logic for 'growing' the trees, albeit it doesn't look very natural how they grow ;-)

What I've discovered however is that by using timelines you can parallelize animations - if you look at the video you'll see that more than one tree grows without disturbing the others doing their thing. I don't know if it is the "correct" way to do stuff like this in JavaFX, but it seems to work.

Still I'm amazed how easy and intuitive it is to create such graphic stuff, and my processor doesn't seem to bother much that I'm painting thousands of Nodes in this little program.

Here is the source code, full source available as a standalone maven project.




Saturday, January 12, 2013

Lets go green and plant some trees.

Every man should plant a tree in his lifetime. Or two. Or more.



The code:





Apart from creating a nice looking visual effect this application also demonstrates how easy it is to group graphic elements together and to bind an eventhandler to it. By using the ready made effects you can easily achieve a hoover effect for free. Maybe you play around with the parameters to create your own personal forrest. It gets quite addictive ;-)

You can also clone the project on the github page so you should be setup in no time. Just clone, change to directory, execute

mvn package 

and, after compiling, execute

java -jar target\plant-some-trees-with-javafx-1.0-SNAPSHOT-jfx.jar

Thanks for reading. Maybe you are also interested in the second part of the (organic) tree visualisation series.

Thursday, January 10, 2013

2D Water Effects with JavaFX and Scala

Join me on my way to a simple water effect using JavaFX and Scala like shown below.


Only recently I've discovered a very nice blog about game tutorials, in particular an article about a 2D water effect got my attention. It amazed me that you only need such simple arithmetic to get such a nice effect. You can read about the basic math at the original article,  see below for my first shot at an implementation in JavaFX.


It is nice to see how much work JavaFX does behind the scenes - you just have to make sure your polygon has the right coordinate list, all the stuff needed for painting is done behind the scenes. By using a simple gradient the water looks nice, too.

Update:


I've pushed the whole project setup to github.

You may notice a small glitch at the beginning of the animation. Some minutes ago I've installed OpenJDK8 early access and started the application without recompiling, and it went away. Why buy new hardware? Just install new VMs ;-)

Monday, January 7, 2013

A sine wave with JavaFX and Scala

My goal is to create a JavaFX application which displays a sine wave like shown in the video below:


Ok.

Here is the source:



Cut'n paste this to your scala-javafx-maven archetype and off you go. 

Friday, January 4, 2013

Compile OpenJFX RT on MacOsX

This time I want to describe what was necessary for me to compile the OpenJFX Project on my laptop, a MacBook Pro running Mountain Lion.
Quoting from the page:
As you can imagine, building a UI toolkit for many different platforms is quite complex. It requires platform specific tools such as C compilers as well as portable tools like ant. The build and project structure of JavaFX like most large projects has evolved over time and is constantly being revised.

I'm writing this early January 2013, maybe things will change in the future. I would love to see a mavenized build for OpenJFX, or even for the whole JDK which would increase adoption tremendously for the whole OpenJDK in my opinion.   

Step 1 to 10 - Checkout the source and do the rest

Mercurial, java, and ant should be installed, then the getting started guide gives you following recipe:

Here is the recipe for building OpenJFX (use a Cygwin shell on Windows):

  • Download the latest JavaFX Developer Preview binary
  • Unzip the binary and put it in ~/closed-jfx
  • mkdir -p ~/open-jfx
  • cd ~/open-jfx
  • hg clone http://hg.openjdk.java.net/openjfx/2.1/master
  • cd master
  • mkdir -p artifacts/sdk/rt
  • cp -r ~/closed-jfx/javafx-sdk2.1.0-beta/rt artifacts/sdk
  • hg clone http://hg.openjdk.java.net/openjfx/2.1/master/rt
  • cd rt
  • Edit build-defs.xml (comment out '<propertycopy name="javac.debuglevel" from="${ant.project.name}.javac.debuglevel" silent="true" override="true"/>')
  • cd javafx-ui-controls
  • ant
..... One hour later: I've followed those instructions, but got in trouble with step one (bravely continued with step 2, though). Searched for a macos binary (didn't know what to search for really?). Decided to go on. Sadly enough, I got stuck some time later with compile errors (Abstract methods not implemented by ... ?! well - this was rather strange.)

But ...


Just before giving it up, I've found after some googling the website of Peter Pilgrim, who just briefly mentioned that the getting started guide was somewhat outdated and after following his instructions I happily compiled openjfx the first time on my laptop!

For further reference, here are the necessary steps to compile OpenJFX:

mkdir openjfx-2.2/
cd openjfx-2.2/
hg clone http://hg.openjdk.java.net/openjfx/2.2/master
cd master
mkdir -p artifacts/sdk/rt/lib
cp $JAVA_HOME/jre/lib/jfxrt.jar artifacts/sdk/rt/lib
hg clone http://hg.openjdk.java.net/openjfx/2.2/master/rt
cd rt
-> edit common.properties, set property javac.debuglevel=lines,vars,source
ant clean dist


The story doesn't end here, in fact I've discovered that there are already efforts on mavenizing openjfx, at least I've found a pom.xml in the rt subdirectory.

With
hg log pom.xml
I've found out that in RT-19825 Adam Bien contributed those pom files.

After commenting the system dependency for the jfxrt.jar (since I've copied the jfxrt.jar into the jre/lib/ext directory by using zonskis maven fix classpath plugin) it happily compiled (by skipping the tests ) using following command :

mvn clean package -Dmaven.test.skip

(Disclaimer: I don't know if the maven build does the same as the ant build does - after inital commit those files seem to be untouched.)

Bottom line for me is that building/compiling (parts of/all of??) OpenJFX was easier than expected. Although I'm sure that this is not the end of the story. I would suspect that the native stuff wasn't compiled?! At least in the 'rt' directory there are only java sources...

The answer to this seems to be that this was only a small part of OpenFX. If you look at the Mercurial index page there are lots of different versions and components for OpenFX:


As you can see, I was only in one sub module of the whole game, but I hope you got the idea how to check out and build the project - it is as simple as described above!

For example, have a look in the openjfx 2.2.6 development:



mkdir openjfx-2.2.6/
cd openjfx-2.2.6/
hg clone http://hg.openjdk.java.net/openjfx/2.2.6/master
cd master
mkdir -p artifacts/sdk/rt/lib
cp $JAVA_HOME/jre/lib/jfxrt.jar artifacts/sdk/rt/lib
hg clone http://hg.openjdk.java.net/openjfx/2.2.6/master/rt
cd rt
-> edit common.properties, set property javac.debuglevel=lines,vars,source
ant clean dist

For the JDK8 branch the procedure works as described, but make sure you set your path to a JDK8. You could of course compile this also from source, but it's maybe easier to get a full JDK8 early access build from here.


ant clean dist for OpenFX-8 (in green)

Small update:

Only recently the structure of the repositories was explained a little bit, quoting Kevin Rushforth:

Each of the following should be treated as a separate forest. You would only grab one of these forests depending on which one you want.
1. The controls team forest:
openjfx/8/controls   openjfx/8/controls/rt   openjfx/8/controls/tests
2. The graphics team forest:
openjfx/8/graphics   openjfx/8/graphics/rt   openjfx/8/graphics/tests
3. The master forest:
openjfx/8/master   openjfx/8/master/rt   openjfx/8/master/tests
The team forests is where the work happens. Each team integrates into the master forest regularly (typically weekly).

Update February 2013:


Note: This tutorial was written early 2013, maybe in the meantime things have changed. There are efforts going on to restructure the build using gradle scripts, so maybe things have changed. This wiki page should be up to date and reflecting the current status of the build.

Have also a look at this video (after reading the whole blog post ;-) on how to do it:




This video shows that compiling JavaFX from source is just some clicks away. 

Wednesday, January 2, 2013

Testing with JemmyFX, JavaFX and ScalaTest

To ease the burden of the testing team, developers should always write automated tests. For JavaFX, there is a library called "JemmyFX" which provides an API to write such tests.


Harold Kantner Special Collection Photo [Photo]
Harold Kantner Special Collection Photo

Using Scala and Scalatest, your tests for JavaFX could look like this:



At the moment of writing this blog post, there was no maven artifact release, but in the Sonatype Snapshot Repository there is one. As such, you would have to add the snapshot repository to your pom and add folowing dependencies to your pom:


<!-- for testing javafx applications -->
<dependency>
<groupId>net.java.jemmy</groupId>
<artifactId>JemmyFX</artifactId>
<version>0.9.3-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.java.jemmy</groupId>
<artifactId>JemmyFXBrowser</artifactId>
<version>0.9.3-SNAPSHOT</version>
 <scope>test</scope>
</dependency>
<dependency>
<groupId>net.java.jemmy</groupId>
<artifactId>Jemmy3Core</artifactId>
<version>0.9.3-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.java.jemmy</groupId>
<artifactId>Jemmy3AWT</artifactId>
<version>0.9.3-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.java.jemmy</groupId>
<artifactId>Jemmy3AWTInput</artifactId>
<version>0.9.3-SNAPSHOT</version>
<scope>test</scope>
</dependency>


A production build should not have dependencies to snapshots of course.

In order for maven to find those artifacts, you have to add the Snapshot Repository to your list of known repositories:


<repositories>
  <repository>
    <id>sonatype snapshots</id>
    <snapshots>
<enabled>true</enabled>
    </snapshots>
    <releases>
<enabled>false</enabled>
    </releases>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
  </repository>
</repositories>



JemmyFX is under heavy development at the moment, but I'm positive a stable release will get published soon. In the meantime the dependencies above give you the ability to implement JemmyFX based tests for your project. Have also a look here for some Java examples how to use JemmyFX.

The scala-javafx-archetype repository at github provides a preconfigured project using the technologies mentioned above.

Small update:


Maybe you want to have a look at the tests for JavaFX for JDK 8 - not long ago the SQE Tests were open sourced here.


nxsw031mac:tests lad$ hg pull
Rufe von http://hg.openjdk.java.net/openjfx/8/master/tests ab
Suche nach Änderungen
Füge Änderungssätze hinzu
Füge Manifeste hinzu
Füge Dateiänderungen hinzu
Fügte 18 Änderungssätze mit 1463 Änderungen an 661 Dateien hinzu
(führe "hg update" aus, um ein Arbeitsverzeichnis zu erstellen)
nxsw031mac:tests lad$ hg update
477 Dateien aktualisiert, 0 Dateien zusammengeführt, 1 Dateien entfernt, 0 Dateien ungelöst


!