Search code examples
scalascalafx

How to declare a property change listener in ScalaFX properly?


Using this code as an example I have written the following to track changes of a slider and put the result into the "speed: Int" variable:

speedSlider.valueProperty.addListener(new ChangeListener[Number] {
  @Override
  def changed(o: ObservableValue[_ <: Number], oldVal: Number, newVal: Number) {
    speed = newVal.intValue()
  }
})

But it causes an error:

wrong number of type arguments for scalafx.beans.value.ObservableValue, should be 2
  def changed(o: ObservableValue[_ <: Number], oldVal: Number, newVal: Number) {

If I change ObservableValue[_ <: Number] to ObservableValue[_ <: Number, _ <: Number] this error disappears but another emerges:

object creation impossible, since method changed in trait ChangeListener of type (x$1: javafx.beans.value.ObservableValue[_ <: Number], x$2: Number, x$3: Number)Unit is not defined
speedSlider.valueProperty.addListener(new ChangeListener[Number] {
                                          ^

Any ideas?

Update: I have resolved the errors by replacing ObservableValue (which was being resolved into the ScalaFX version which I don't really understand) with javafx.beans.value.ObservableValue. It compiles and throws no errors now, but still doesn't work - the code is never invoked.


Solution

  • Looking at the docs I see you don't need to pass a ChangeListener but simply an anonymous function with the same signature as the onChange method

    speedSlider.valueProperty.addListener{ (o: javafx.beans.value.ObservableValue[_ <: Number], oldVal: Number, newVal: Number) =>
      speed = newVal.intValue
    }
    

    Otherwise the method will expect a javafx.beans.value.ChangeListener

    I hope this solves the issue.