Skip to content

Latest commit

 

History

History
58 lines (44 loc) · 3.21 KB

README.md

File metadata and controls

58 lines (44 loc) · 3.21 KB

sfx

A lightweight set of Scala wrappers for JavaFX.

Motivation

sfx was inspired by the excellent ScalaFX project. Indeed, the original author of sfx contributed to the ScalaFX project before founding sfx.

So, why start another Scala/JavaFX project? In our opinion, ScalaFX suffers from a number of drawbacks, the primary cause of which is a design decision to wrap a JavaFX class instance as a delegate inside an equivalent ScalaFX class. For example:

class SomeScalaFXClass (delegate: SomeJavaFXClass) {...}

This has the following drawbacks:

  1. The ScalaFX version of the class must provide wrappers for every single public member of its associated JavaFX class. This is a boring chore for the developers of ScalaFX, and many of the duplicated members provide little in the way of added-value to users of the library.
  2. While the resulting ScalaFX and JavaFX classes are interchangable, through implicit conversion functions, there can be a lot of thrashing about between the two. In particular, every time a JavaFX instance is converted to its ScalaFX equivalent, a new instance of the ScalaFX class is created. This can lead to a lot of temporary ScalaFX instances being created, resulting in unncessary memory conversion/garbage collection processing overhead.
  3. Having both a ScalaFX and a JavaFX version of just about every GUI element is confusing for users, particularly if they are interoperating with plain JavaFX code.
  4. Using FXML files with ScalaFX is not as straightforward as it could be.
  5. User sub-classing of ScalaFX classes is non-trivial.

In addition, we wanted to make use of functional reactive programming (FRP) techniques for interacting with JavaFX, and also wanted to be able to work with JavaFX with Akka actors (which is nontrivial using ScalaFX).

Our approach makes use of a relatively new Scala feature: implicit classes.

This allows us to write very simple class definitions, such as:

implicit class SomeScalaWrapper (delegate: SomeJavaFXClass)
extends AnyVal {...}

This fairly trivial change has some interesting implications:

  1. Users work solely with JavaFX classes, and should never create instances of the Scala wrapper classes. This simplifies how Scala users interact with JavaFX, including working with custom JavaFX subclasses and FXML.
  2. Having an implicit class extend from AnyVal is a hint to the Scala compiler that it does not need to create instances of the wrapper class—it simply re-uses the sole constructor argument as is. This eliminates the memory and conversion/garbage collection processing overhead of using delegate classes.
  3. Members of the Scala wrapper class are then used to decorate the JavaFX class, and so only members that add value need be defined. (This is the same approach that the Scala library adopts when referencing certain Java classes, such as Java's primite wrapper classes, the String class, etc.)

We welcome any comments, suggestions and/or contributions to this project. Feel free to fork our code and send us your pull requests...