What is New in ScalaFX 1.0 Milestone 5

ScalaFX helps you simplify creation of JavaFX-based user interfaces in Scala. ScalaFX uses a simple, hierarchical pattern for creating new objects and building up the scene graph. ScalaFX supports full interoperability with Java and can run anywhere the Java Virtual Machine (JVM) and JavaFX2 are supported.
ScalaFX 1.0 M5 supports most of the JavaFX 2.2.25 functionality, (distributed with Java 1.7.0_u25).

Summary of Changes since Milestone 4

  • Major improvements to Chart’s API – charts can be created without need to use JavaFX type parameters and the same hierarchical build pattern as in the rest of ScalaFX.
  • Easier way to create, add and remove event handlers and event filters that handle more than one event.
  • New implicit conversions from color from tuples.
  • New wrapper for `VerticalDirection`.
  • Added several of new demos, improved a couple of the existing ones.
  • Several bug fixes, including issues 61, 66, 67 and 70.
  • Internal code cleanup and simplification.
  • Several improvements to build system, tests, upgrades to dependent libraries and SBT plugins.

New and Improved

Major improvements to chart’s API

The focus was on making the chart API easier to use, in particular, to remove to able to create charts without using JavaFX type parameters (Issue 79) and being able to use ScalaFX’s hierarchical build pattern (Issue 72). The improvements are illustrated in this complete example of creating an application that displays a Pie Chart:

import scalafx.application.JFXApp
import scalafx.collections.ObservableBuffer
import scalafx.scene.Scene
object PieChartDemo extends JFXApp {
  val dataPairs = Seq(("Sun", 25), ("IBM", 17), ("HP", 25), ("Dell", 27), ("Apple", 5))
  stage = new JFXApp.PrimaryStage {
    title = "PieChartDemo"
    scene = new Scene {
      root = new PieChart() {
        title = "Pie Chart"
        clockwise = false
        data = ObservableBuffer(dataPairs.map {case (x, y) => PieChart.Data(x, y)})
      }
    }
  }
}

pie-chart

There are a couple of new demos of charts available.

Easier way to create, add and remove event handlers and event filters

Focus here was on making it easier to create event handlers and event filters that deal with more than one event (Issue 77). That may be useful for instance in code that handles mouse interaction, especially when that interaction is context dependent. Here is a code snipped illustrating use of the new/improved `handleEvent` construct:

  val pane = new Pane() {...}
  // Define handling of mouse events and add it to the pane
  val subscription = pane.handleEvent(MouseEvent.Any) {
    me: MouseEvent => {
      me.eventType match {
        case MouseEvent.MousePressed => {...}
        case MouseEvent.MouseDragged => {...}
        case _ => {...}
      }
    }
  }
  ...
  // Remove event handler when interaction is no longer needed
  subscription.cancel()

There are two new demos that illustrate this in more details: RectangleDrawingDemo and MultipleShapeDrawingDemo.

New implicit conversion for colors

You can now assign RGB color using tuples instead us using `Color.rgb(…)` methods, for instance:

import scalafx.Includes._
import scalafx.scene.shape.Rectangle
...
  val r = new Rectangle {
    // Instead of: fill = Color.rgb(64, 128, 196, 0.5)
    fill = (64, 128, 196, 0.5)
    // Instead of: stroke = Color.rgb(187, 56, 19)
    stroke = (187, 56, 26)
    // or using interpreting Int as hex values
    stroke = 0xBB381A
  }

New demos

There are several new demo, most illustrate improvements to charts and event handling.

Improved demos

A few demos were improved. It is now also possible to easily run any demo from SBT, it used to default to ColorfulCircles demo.

  • MenuBarTest – improve layout – menu fill the top line, is not truncated on the right.
  • MenuTest – add examples of event handlers for menu items.
  • VideoCubesDemo – do not use hard coded locations to external files, use system property

Internal code cleanup and simplification

  • New `EventHandlerDelegate` trait to remove duplicate code for add/removeEventHandler/Filter in `Node`, `MenuItem`, `TableColumn`, `TreeItem`, and `Window`.
  • Provide explicit ScalaFX types in some additional cases when JavaFX types were inferred, to simplify API usage.
  • Improved handling of `null` assigned to a property – Some properties could be legally assigned `null` value. In this release more places are fixed where this used to lead to `NullPointerException`.

In SBT, fork tests so they are run on a separate JVM, but do not run individual tests is parallel

ScalaFX tests require initialization of JavaFX application thread. Running tests on a separate JVM avoids conflicts caused by JavaFX application thread initializations. It used to be that test can be run only once and SBT has to be restarted; now you can rerun tests without in the same SBT instance.

Build system and dependency upgrades

  • Use SBT 0.13
  • Scala 2.10.1 upgraded to 2.10.2
  • JUnit 4.10 to 4.11
  • Sbt-idea 1.3.0 to 1.5.1
  • Sbteclipse-plugin 2.1.1 to 2.2.0

Bug Fixes

  • Issue 61 – method ProgressBarTableCell#forTableColumn() did not work correctly.
  • Issue 66 – Wrapper classes should not be `final` – this prevents use of hierarchical builder pattern. Also update related VideoCubeDemo demo.
  • Issue 67 – MediaPlayer – simplify handling of Runnable. Do it without introducing overly generic implicit conversion of a code block to Runnable.
  • Issue 70 – could not compile code that used ‘EventHandler#handleEvent(…){…}'”.
  • TableColumn#removeEventHandler actually called delegated call to addEventHandler
  • Node#onTouchReleased and Scene#onTouchReleased actually delegated to onTouchPressed

Where to Get It

You can download ScalaFX binaries and source code from the project website.

Artifacts are also published on the Maven Central, so you can use them from you favorite build system SBT, Gradle, Maven, etc.

Advertisements

Getting Started with ScalaFX: Compile and Run

ScalaFX is a Scala library for creation user interface applications based on JavaFX platform. Its intention is to be simpler to use and more “Scala-like” compared to the underlying JavaFX API.

This post is intended to help you setup a basic Scala project that is using ScalaFX library. The setup only requires dependencies on the ScalaFX, JavaFX, and the Scala libraries. If you add those three libraries you are good to go and develop ScalaFX application.

We will cover steps to do the setup using SBT build script. SBT is a build tool for Scala and Java projects.  SBT is de-facto standard build system for many Scala projects. Even if you do not use it, it is good to be familiar with it. You can also use an SBT build script for creating Eclipse, IDEA, NetBeans, and Maven setups (covered in a future post).

In our example we will compile and run a simple ScalaFX demo:

package hello

import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.geometry.Insets
import scalafx.scene.Scene
import scalafx.scene.control.Label
import scalafx.scene.layout.BorderPane

object HelloSBT extends JFXApp {
  stage = new PrimaryStage {
    scene = new Scene {
      root = new BorderPane {
        padding = Insets(25)
        center = new Label("Hello SBT")
      }
    }
  }
}

The demo opens a window and displays text “Hello SBT” in the center:

hello-sbt

Prerequisites

As the minimum starting requirement you only need to install Java SDK and SBT. Everything else needed to compile and run ScalaFX applications will be downloaded by SBT automatically.

You will also need a text editor to edit. Any decent test editor will do, for instance, jEdit or Sublime Text.

1. Install Java 7

I assume that you have Java 7 installed on your system. If you do not, you can download latest version from Oracle’s Java SE page.

2. Set JAVA_HOME environment variable

JavaFX is distributed with recent Java 7 releases, but it is not automatically added to class path. You need to define environment variable JAVA_HOME pointing to the installation directory of the JDK. This variable will be used by SBT script to locate JavaFX binaries: jfxrt.jar.

On Windows the installation directory will be something like:

  C:\Program Files\Java\jdk1.7.0_21

on Linux it could be:

  /usr/lib/jvm/default-java

3. Install SBT

If you do not have SBT on your system install it following steps on “SBT Setup” page. To test the installation open command prompt and type (without “>”):

  > sbt sbt-version

If SBT is installed properly, it should respond with a series of printouts. If the is the first time you run SBT it will complete installation by downloading some dependencies needed by SBT. At the end SBT should print version information, for instance:

  ...
  [info] 0.12.3

Building and Running ScalaFX Apps using SBT

SBT can be used to easily build and run Scala and Java. SBT assumes default organization of files in you project:

  src/
    main/
      resources/
        <files to include in main jar here>
      scala
        <main Scala sources>
      java/
        <main Java sources>
    test/
      resources
        <files to include in test jar here>
      scala/
        <test Scala sources>
      java/
        <test Java sources>

If you are familiar with Maven, the SBT directory structure is the same. For instance, in your project directory Scala sources located in subdirectory src/main/scala.

1. Create “hello-sbt” project directory

Let’s first create a directory for our sample projects, call it, for instance, hello-sbt. We will add content as we progress. At the beginning our project directory is empty.

2. Create SBT configuration file

In the newly create directory create new file called build.sbt with the following content:

// Name of the project
name := "Hello SBT"

// Project version
version := "1.0"

// Version of Scala used by the project
scalaVersion := "2.10.1"

// Add dependency on ScalaFX library
libraryDependencies += "org.scalafx" %% "scalafx" % "1.0.0-M3"

// Add dependency on JavaFX library based on JAVA_HOME variable
unmanagedJars in Compile += Attributed.blank(file(System.getenv("JAVA_HOME") + "/jre/lib/jfxrt.jar"))

Note that each declaration is separated by a blank line. This is required by SBT. The first two declarations define our projects name and version. The third one specifies which version of Scala we want to use. The forth one, libraryDependencies += …, defines managed dependency on the ScalaFX library. Managed dependencies are automatically downloaded by SBT from Maven Central. The last declaration “unmanagedJars in Compile” instructs SBT where to look for JavaFX library. It is unmanaged meaning that SBT will not attempt to download it on its own. We make use of the JAVA_HOME environment variable defined earlier to point to location of JavaFX runtime: jfxrt.jar.

3. Create simple ScalaFX application

By default, SBT looks for Scala source files in subdirectory src/main/scala of you project. For our example we will use package name hello. Inside our project directory, next to build.sbt create nested directories src/main/scala/hello.

Inside inside src/main/scala/hello create HelloSBT.scala:

package hello

import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.geometry.Insets
import scalafx.scene.Scene
import scalafx.scene.control.Label
import scalafx.scene.layout.BorderPane

object HelloSBT extends JFXApp {
  stage = new PrimaryStage {
    scene = new Scene {
      root = new BorderPane {
        padding = Insets(25)
        center = new Label("Hello SBT")
      }
    }
  }
}

4. Run your application using SBT

At this point you should have everything needed to build and run the sample application. Open command prompt and change directory to the hello-sbt project (where build.sbt is located).

  > sbt run

If everything is installed and configured fine, SBT will compile the code and run your code. The SBT output will look something like:

  The system cannot find the file C:\Apps\sbt\bin\sbtconfig.txt.
  [info] Updating ...  
  [info] Resolving ...
  ...
  [info] Done updating.
  [info] Set current project to Hello SBT (…)
  [info] Updating {file:…}...
  [info] Resolving org.scala-lang#scala-library;2.10.1 ...
  [info] Resolving org.scalafx#scalafx_2.10;1.0.0-M3 ...
  [info] Done updating.
  [info] Compiling 1 Scala source to …/hello-sbt/target/scala-2.10/classes...
  [info] Running hello.HelloSBT

hello-sbt

Congratulations! Now you know how to compile and run ScalaFX code using SBT.

Closing Thoughts

You can follow steps in this post to create your own SBT project file for ScalaFX. SBT is well documented with an easy to follow “Getting Started” guide.

To learn more about ScalaFX visit the home page, check links and user groups there. The best ways to learn ScalaFX is to learn JavaFX first. There are numerous JavaFX tutorials on the Oracle website. I recommend getting a copy of the “Pro JavaFX 2” book, one of the coauthors is creator of ScalaFX Steve Chin. ScalaFX versions of the examples from the “Pro JavaFX 2” book are on GitHub project ProScalaFX.

The source for this post is in GitHub ScalaFX-Tutorials project under hello-sbt.

ScalaFX v.1.0 Milestone 3 Released

The third milestone of ScalaFX v.1.0 is now available on our Downloads page and in the Maven repository.

ScalaFX helps you simplify creation of JavaFX-based user interfaces in Scala. ScalaFX uses a simple, hierarchical pattern for creating new objects and building up the scene graph. ScalaFX supports full interoperability with Java and can run anywhere the Java Virtual Machine (JVM) and JavaFX2 are supported. Current version supports most of the JavaFX 2.2.7 functionality. For more information see ScalaFX home page.

Changes since Milestone 2:

  • Improvements to handling of collections within ScalaFX code For instance, utility functions added to help filling collections and deal with null passed from the user.
  • Improvements to scaladocs.
  • Missing methods added to Scene: fill, addMnemonic, removeMnemonic, getMnemonics, accelerators, snapshot, startDragAndDrop, startFullDrag.
  • Additional Font factory methods.
  • Fixed Issue 39: scalafx.scene.control.Pagination PageFactory is not working
  • Fixed Issue 45: Missing wrappers for ReadOnly[Boolean,Double,Float,Integer,Long,String]Wrappers
  • Fixed Issue 57: Control should extend Parent not Node.
  • Work around for Scala 2.10 bug SI-7269 that was causing one of the test in ObservableMapSpec to fail. Please add your votes for the fix.
  • Added some factory methods for ReadOnlyObjectWrapper as a workaround for Issue 14.
  • Sbt-idea updated to v.1.3.0 for improved IDEA project generation.

ScalaFX v.1.0 Milestone 2 Released

The second milestone of ScalaFX v.1.0 is now available on ScalaFX Downloads page and in the Maven repository.
ScalaFX helps you simplify creation of JavaFX-based user interfaces in Scala. ScalaFX uses a simple, hierarchical pattern for creating new objects and building up the scene graph. ScalaFX supports full interoperability with Java and can run anywhere the Java Virtual Machine (JVM) and JavaFX2 are supported. Current version supports most of the JavaFX 2.2.* functionality. For more information see ScalaFX home page.
Changes since Milestone 1:
  • Minimized need for implicit conversions in user code by using ScalaFX wrappers as arguments and return values of many methods (forcing the conversions to be compiled in ScalaFX). It is now possible, in many cases, to skip
    import scalafx.Includes._
  • When `null` is assigned to a collection, clear its entries rather than making it `null`.
  • Fixed Issue 9: ClassCastException when working with Binding Expression
  • Work around for Issue 14 added – use ObjectProperty factory methods instead of constructors, see example here.
  • Several issues were resolved to enable simple creation of TableViews: Issue 10404143, and 44.
  • New TableViews examples were added.
  • Fixed Issue 42: enable direct assignment of items to ContextMenu.
  • Resolved 3 out of 4 tests failing in ScalaFX 2.10. The fix for the remaining one is scheduled for M3.
  • Upgraded default Scala version to 2.9.3. Scala 2.10 compiler upgraded to v.2.10.1.