Steve On Java - JavaFX

Hacking Java, JavaFX, and Flash with Agility
  • rss
  • Home
  • NightHacking Tour
    • [Archive] NightHacking Europe – The Road to Devoxx
  • SvJugFX
  • JFXtras
    • JFXtras Individual CLA
    • JFXtras Corporate CLA
  • 2013 Travel Map
    • Let’s Meetup!
    • 2012 Travel Map
  • Contact

JavaFX 2.0 and Scala, Like Milk and Cookies

steveonjava | September 27, 2011

JavaFX 2.0 and Scala are both great technologies individually, but work even better when used together.  JavaFX 2.0 is a powerful rich client technology with advanced graphics, animation, and media capabilities.  Scala is a simple, yet powerful language with advanced language features for writing domain-specific languages (DSLs).  Add a little Scala UI DSL to your JavaFX 2.0 project and you will be in cookie and cream heaven!

Time Lapse Photography Creative Commons Licensed by Robbie’s Photo Art

JavaFX Colored Circles

I will go into more detail on why Scala in a bit, but I believe this is all best illustrated with a code example.  One of the basic examples of JavaFX 2.0 functionality that comes with the SDK is a sample application called ColorfulCircles.  The full source code can be found here:

Java Colored Circles Code

With the help of Sven Reimers, we ported this to Scala on top of the ScalaFX library.  The working application source can be found here:

ScalaFX Colored Circles Code

Update: Dean Iverson has a great example of the same code in GroovyFX

Feel free to peruse the source code at your leisure, and take note of the following:

1. ScalaFX is More Concise

The ScalaFX version is shorter both in number of lines and more importantly number of characters.

Code Count (excluding licenses and imports):

  • Lines:
    • Java: 48
    • ScalaFX: 42
  • Characters:
    • Java: 1602
    • ScalaFX: 866

This is due to custom tailored DSL language that is fully expressive with less redundancy.  In the Java version of the code you will notice a lot more boilerplate and syntactic repetition that is required by the language.

2. ScalaFX Code Looks Like the Output

While the output of the Colored Circles example is quite simple, it actually hides quite a bit of complexity in the way it is structured.  Here is the output run from JavaFX 2.0 Build 45 using ScalaFX:

What you are actually seeing is a SceneGraph composed of the following layers:

  • A Scene with a black background that contains…
    • A Group that contains
      • 30 semi-transparent Circles covered by…
    • A rainbow-colored Rectangle overlay

When reading the ScalaFX code you get this nesting through the object-literal style declaration of the Nodes in the Scene as excerpted here:

// ScalaFX Scene Excerpt:
scene = new Scene {
  content = Seq(
    new Group {
      circles = for (i <- 0 until 30) yield new Circle { ... }
    }
    new Rectangle { ... }
  )
}

However, the Java version does not give you the same hierarchical representation, and instead uses an imperative series of calls to constructors, getters, and collection methods.

3. Tailored Animation Syntax

Animations are very commonly used in creating good UIs, which is why JavaFX Script had a built-in construct to simplify the creation of animations. ScalaFX has a similar syntax that allows you to quickly and easily create animations, which is used in the ColorfulCircles example:

Seq(
  at(0 s) {circle.centerX -> random * 800},
  at(0 s) {circle.centerY -> random * 600},
  at(40 s) {circle.centerX -> random * 800},
  at(40 s) {circle.centerY -> random * 600}
)

This makes it trivially easy to create complex animations.

4. And the ScalaFX Version Has a Hidden Bonus Feature…

Unlike the JavaFX version, the contents are bound to the width and height of the stage. Binding in ScalaFX is as simple as replacing the assignment operator (=) with the bind operator (<==) as shown here:

// ScalaFX Property Setting:
width <== scene.width
height <== scene.height

While this is a simple operator change in ScalaFX, it requires complex enough code that they decided to omit it from the JavaFX sample. A loose translation to Java would be the following:

// Java Fixed Property Binding
colors.widthProperty().bind(scene.widthProperty())
colors.heightProperty().bind(scene.heightProperty())

Although, the precise equivalent code in Java syntax would actually be the following:

// Java Dynamic Property Binding
colors.widthProperty().bind(Bindings.selectDouble(primaryStage.sceneProperty(), "width"))
colors.heightProperty().bind(Bindings.selectDouble(primaryStage.sceneProperty(), "height"))

Either of these versions is quite a bit more complex and unwieldy than the ScalaFX equivalent, and this is for a very simple binding!

About ScalaFX

ScalaFX is a UI DSL written within the Scala Language that sits on top of JavaFX 2.0 (not to be confused with Ingo Maier’s great work on Functional Reactive Programming for Swing). This means that every ScalaFX application is also a valid Scala application. By extension it supports full interoperability with Java and can run anywhere the Java Virtual Machine (JVM) and JavaFX 2.0 are supported.

Some of the features of ScalaFX include:

A Programmer-Friendly Object-Literal-Like Syntax

ScalaFX uses a simple, hierarchical pattern for creating new objects and building up the scene graph.  Here is a simple example that creates a new stage with a rectangle that changes color based on mouse events:

stage = new Stage {
  title.value = "Hello Stage"
  width = 600
  height = 450
  scene = new Scene {
    fill = Color.LIGHTGREEN
    content = new Rectangle {
      x = 25
      y = 40
      width = 100
      height = 100
      fill <== when (hover) then Color.GREEN otherwise Color.RED
    }
  }
  visible = true
}

Unlike the builders you find in the core JavaFX APIs, the ScalaFX object declaration syntax uses the normal object API. This means that you can use the same operators and convenient syntax to create and modify your scene graph. Also, anything that is permissible in a Scala block (such as variable declarations, method calls, binding, etc.) can also be done inline while constructing objects. For JavaFX builders you need to declare binding after you finish creating your objects, which leads to disassociated and hard to maintain code.

Natural Language Bind Expressions

One of the greatest advantages of using the Scala language as a DSL is the rich support for operators as methods. This is similar to the C++ concept of operator overloading, but much more uniform and clean in its application.

The ScalaFX bind library exposes normal operators such as &&, ||, +, -, *, / on top of all bindable objects. Also, Scala supports operator precedence, so it looks and feels like you are writing normal expressions even though you are creating bound objects under the covers. As a result, you have the full functionality available from the JavaFX 2.0 binding libraries with code that looks akin to mathematical expressions and operators.

Here are some examples of what you can do with the ScalaFX bind API:

Infix Addition/Subtraction/Multiplication/Division/etc.

height <== rect1.height + rect2.height

Aggregate Operators

width <== max(rect1.width, rect2.width, rect3.width)

Conditional Expressions

color <== when (hover) then Color.GREEN otherwise Color.RED

Complex Boolean Expressions and String Concatenation

text <== when (rect.hover || circle.hover && !disabled) then textField.text + " is enabled" otherwise "disabled"

Free-form Invalidation and Change Handlers

rect.hover onInvalidate {
  needsRepaint = true
}

Fully Type-Safe APIs

This may seem like an insignificant point…  Type safety is something that Java developers have always had (and often take for granted), and developers in other scripting languages live without (and unknowingly suffer with runtime errors as a result). However, it is a critical feature if you are developing applications that cannot have unexpected runtime errors and bugs after deployment.

A good compiler will be able to pick up many common coding mistakes through comparison of expected and actual types, and a great compiler (like Scala) will automatically infer types for you so you don’t have to tediouisly repeat them throughout your code.

ScalaFX gets the best of both worlds with a scripting-like DSL syntax where you can rarely have to explicitly type objects, with the strong type-safety of the Scala compiler that will infer and check the types of every expression and API call. This means less time spent debugging weird code bugs and misspellings, and higher quality code right out of the gate!

Seamless JavaFX/ScalaFX Interoperability

It is often the case that you do not have complete freedom about the predominant language of the codebase, or of the libraries you are including functionality from.  Even in a mixed environment codebase where you have Java, Scala, and possibly other JVM languages, ScalaFX will seamlessly convert and interoperate.

ScalaFX gets this functionality through the implicit operator capabilities of Scala.  Anywhere your program expects a JavaFX typed object, it will automatically insert the code to convert from ScalaFX wrapped objects to JavaFX native classes.  Any time you use a ScalaFX specific feature, the compiler automatically creates a ScalaFX wrapper object that allows you to call advanced methods and access the full functionality. This all happens behind the scenes, letting you focus on writing clean code, and not fussing about integration and interoperability.

With all this interoperability magic happening behind the scenes, there is some additional overhead on your application. We have taken pains to minimize this using features like @specialize in the Scala language, which allows us to avoid boxing and unboxing costs on primitives. However, without real benchmarks it is hard to tell just how good of a job we have done. Hopefully more on this in a future post.

Finding out More About ScalaFX

The ScalaFX project site is hosted by Google Code including a couple mailing lists that you should join if you are interested:

  • ScalaFX Users
  • ScalaFX Developers

At the time of writing we do not have a bundled release, but are interested in early adopter feedback.  If you would like to give it a try, please download the source and give it a quick spin!

I will have more details about ScalaFX at my upcoming JavaOne session with Dean Iverson entitled “JavaFX 2.0 With Alternative Languages“.  Come to hear more about Scala, Groovy, and other JVM languages you can use to write simpler, cleaner code.

 

Share this:

  • Twitter
  • Google +1
  • More
  • Facebook
  • LinkedIn
  • Email
Categories
JavaFX, ScalaFX
Tags
dsl, JavaFX, javafx 2.0, ScalaFX
Comments rss
Comments rss
Trackback
Trackback

« Steveonjava Track at JavaOne JavaOne is Rebuilding Momentum »

12 Responses to “JavaFX 2.0 and Scala, Like Milk and Cookies”

  1. PhiLho says:
    September 27, 2011 at 5:33 am

    Aah, at least! I started to play with JavaFX from Scala , but so far only did a simple conversion from Java to Scala, meeting some issues (needing instanceOf) and lacking the nice syntax I saw in the slides: I don’t master Scala yet, so I cannot do such DSLs myself.
    I guess lot of people did the same thing, reinventing the wheel each time.

    I am glad you released this code, I am eager to start using it.

    Reply
  2. Knut Arne Vedaa says:
    September 27, 2011 at 11:45 am

    Great work! JavaFX and Scala seems like a match made in heaven.

    Reply
  3. CC says:
    September 30, 2011 at 11:35 am

    I have been waiting for this. Very good news indeed.

    Reply
  4. Eric Kolotyluk says:
    September 30, 2011 at 3:25 pm

    I thought this was supposed to be an article about JavaFX and Scala – all you are doing is just showing off JavaFX Script.

    Sorry, that was my poor attempt at humor :-)

    I am impressed at how much it looks like FX Script though. This was always my big complaint about FX Script – that it looked so similar to Scala, why did I have to learn ‘yet another language?’ Don’t get me wrong, I liked FX Script, it was very expressive, but it was not complete enough to write an entire application – in particular concurrent code.

    By the way, what is the concurrency model in JavaFX with Scala?

    This is an excellent example of why the DSL capabilities in Scala are so useful. Well done!

    Reply
    • steveonjava says:
      October 1, 2011 at 5:30 am

      For the ScalaFX base Application class I made sure that all the initialization code gets fired in the JavaFX event thread (three cheers for DelayedInit!)

      For application code that needs multi-threaded execution, you can use the javafx.concurrent package directly (with Services and Tasks), but I hope to have a more Scala-like solution in the future.

      Reply
  5. Nicolas says:
    October 17, 2011 at 8:50 am

    Wow, I was just introduced to JavaFX and all through the presentation I kept thinking: how would this look in Scala?

    Lo and behold: it looks awesome. I’m going to start playing with it asap. Great work!

    Reply
  6. scalingout says:
    October 24, 2011 at 12:00 pm

    Get this to work on Android (like some of your JavaFX posts from the past), and you will really have something attractive…

    Reply
  7. Eric Kolotyluk says:
    December 28, 2011 at 3:18 am

    OK, I finally got around to trying this. The good news I got it to work, but the bad news is that it took me about 2 hours to figure it out. I really look forward to some improved resources on ‘getting started.’

    Reply
    • steveonjava says:
      December 28, 2011 at 3:38 am

      Glad you got it working… probably need to build a distribution jar and do an alpha release to make this process easier… will get to this after my current book deadline unless someone else volunteers.

      Reply
  8. Lonn Furry says:
    February 13, 2012 at 6:40 am

    Scala is very attractive for on one hand, it is a much more powerful programming language, and on the other hand, a Scala method can call any Java method as easy as another Java method does so. A Java method can also easily call a Scala method with certain limitations.

    Reply
  9. Rakesh Amety says:
    August 21, 2012 at 2:36 am

    Hi Steve,

    In one of our project we are trying to integrate node.js with javafx for chat.
    Please suggest is there any way to achieve.

    Any inputs on this would be great help.

    Thanks

    Reply
    • steveonjava says:
      August 21, 2012 at 12:05 pm

      A little off topic for this blog post, but I don’t think it should be hard to do what you are attempting. JavaFX lets you use and Java network/remoting library, so just pick a protocol that works well for chat (jabber might not be a bad place to start), and then find implementations on the front-end for Java and back-end for node.js.

      Reply

Leave a Reply

Click here to cancel reply.

  • Travel Map - Let's Meetup

Publications

  

Affiliations

Awards

2009/2011 JavaOne Rock Star!

Disclaimer

Views and opinions expressed here are all my fault... complain to me, not my employer. :)
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox
loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.