ScalaFX: Problems with Tables abound

Doing a lot with all kinds of tables in ScalaFX, I stumbled upon a bug in ScalaFX that, with the help of the bug report, I was able to circumvent. It is a subtle bug where types are mixed between scalafx.SOMETHING and the corresponding javafx.SOMETHING.

In one of the answers it is stated that:

The issue is with implicit conversion from TableColumn not being located by Scala. I am not clear why this is happening (maybe a Scala bug).

But the provided work-around at least made it work. Until today I stumbled onto a (probably) just another instance of this bug, but where the same work-around does not help. I am using TreeTableViews and try to replace the children of the root by filtering out one element. The code I use is of course very different, but here is a reduced and fully contained example, based on the original bug report and adapted to use a TreeTableView:

import scalafx.Includes._
import scalafx.scene.control.TreeTableColumn._
import scalafx.scene.control.TreeItem._
import scalafx.application.JFXApp.PrimaryStage
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.layout._
import scalafx.scene.control._
import scalafx.scene.control.TreeTableView
import scalafx.scene.control.Button
import scalafx.scene.paint.Color
import scalafx.beans.property.{ObjectProperty, StringProperty}
import scalafx.collections.ObservableBuffer


// TableTester.scala
object TableTester extends JFXApp {

  val characters = ObservableBuffer[Person](
    new Person("Peggy", "Sue", "123", Color.Violet),
    new Person("Rocky", "Raccoon", "456", Color.GreenYellow),
    new Person("Bungalow ", "Bill", "789", Color.DarkSalmon)
  )

  val table = new TreeTableView[Person](
    new TreeItem[Person](new Person("","","",Color.Red)) {
      expanded = true
      children = characters.map(new TreeItem[Person](_))
    }) {
    columns ++= List(
      new TreeTableColumn[Person, String] {
        text = "First Name"
        cellValueFactory = {
          _.value.value.value.firstName
        }
        prefWidth = 180
      },
      new TreeTableColumn[Person, String]() {
        text = "Last Name"
        cellValueFactory = {
          _.value.value.value.lastName
        }
        prefWidth = 180
      }
    )
  }

  stage = new PrimaryStage {
    title = "Simple Table View"
    scene = new Scene {
      content = new VBox() {
        children = List(
          new Button("Test it") {
            onAction = p => {
              val foo: ObservableBuffer[TreeItem[Person]] = table.root.value.children.map(p => {
                val bar: TreeItem[Person] = p
                p
              })
              table.root.value.children = foo
            }
          },
          table)
      }
    }
  }
}

// Person.scala
class Person(firstName_ : String, lastName_ : String, phone_ : String, favoriteColor_ : Color = Color.Blue) {

  val firstName = new StringProperty(this, "firstName", firstName_)
  val lastName = new StringProperty(this, "lastName", lastName_)
  val phone = new StringProperty(this, "phone", phone_)
  val favoriteColor = new ObjectProperty(this, "favoriteColor", favoriteColor_)

  firstName.onChange((x, _, _) => System.out.println(x.value))
}

With this code what one gets on compilation with the latest Scala and ScalaFX is:

[error]  found   : scalafx.collections.ObservableBuffer[javafx.scene.control.TreeItem[Person]]
[error]  required: scalafx.collections.ObservableBuffer[scalafx.scene.control.TreeItem[Person]]
[error]               val foo: ObservableBuffer[TreeItem[Person]] = table.root.value.children.map(p => {
[error]                                                                                          ^
[error] one error found

And in this case, adding import statements didn’t help, what a pity. Unfortunately this bug is open since 2014 with a helpwanted tag and nothing is going on. I guess I have to try to dive into the source code of ScalaFX 🙁

1 Response

  1. 2017/11/19

    […] ScalaFX: Problems with Tables abound […]

Leave a Reply

Your email address will not be published. Required fields are marked *