Tag Archives: scalafx

ScalaFX 8u40 – TextFormatter – part 1

Upcoming release of JavaFX 8u40 will bring several enhancements, including dialogs and new spinner control. ScalaFX started new branch, SFX8u40, to support JavaFX 8u40. Earlier post described Spinner control. In this two-part post we will cover TextFormatter and related features.

TextFormatter lets you edit custom values in text controls, like TexFIeld, Text Area, and other derived from TextInputControl. Say that you want to use a TextField to enter numbers. The new `textFormatter` property lets you directly interact with a number in a TextInputControl rather than its textual representation. For instance, you can bind other properties to that number.

Let’s look at a simple example where a TextField represent some amount of a currency, say US dollars. First thing is to create a StringConverter for converting between string like “$67.98” and a number. We can use number format provide by Java’s NumberFormat:

val currencyFormat = NumberFormat.getCurrencyInstance(Locale.US)
val converter = new FormatStringConverter[Number](currencyFormat)

To see how binding works, lets create a simple slider:

val slider = new Slider(0, 10000, 1000)

TextField can bind it’s a numeric value to the slider. The numeric value is accessible though textFormatter’s value property:

new TextField {
  textFormatter = new TextFormatter (converter) {
    value <==> slider.value
  }
}

Here is ScalaFX demo application that displays text field (formatted as a currency) and a slider that can modify value of the text field.

011 - ScalaFX 8u40 - TextFormatter

import java.text.NumberFormat
import java.util.Locale

import scala.language.implicitConversions
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.geometry.Insets
import scalafx.scene.Scene
import scalafx.scene.control.{Slider, TextField, TextFormatter}
import scalafx.scene.layout.{Region, VBox}
import scalafx.util.converter.FormatStringConverter

object TextFormatterDemo extends JFXApp {

  val slider = new Slider(0, 10000, 1000)

  val textField = {
    val currencyFormat = NumberFormat.getCurrencyInstance(Locale.US)
    val converter = new FormatStringConverter[Number](currencyFormat)
    new TextField {
      textFormatter = new TextFormatter(converter) {
        value <==> slider.value
      }
      maxWidth = 140
      maxHeight = Region.USE_COMPUTED_SIZE
    }
  }

  stage = new PrimaryStage {
    scene = new Scene(300, 200) {
      title = "TextFormatter Demo"
      root = new VBox {
        content = Seq(textField, slider)
        padding = Insets(20)
        spacing = 12
      }
    }
  }

  slider.requestFocus()
}

The TextFormatter support is available in latest SNAPSHOT releases of ScalaFX 8u40. To use it add following to your SBT build file:

libraryDependencies += "org.scalafx" %% "scalafx" % "8.0.40-SNAPSHOT"

Above we showed a simpler scenario of using TextFormatter where we specified string converter. There are another ways, with higher degree of control. TextFormatter can have a filter that monitors and modifies changes to the text, caret, and selection before they are displayed on the screen. This will be subject of the part 2 of this blog post.