Question

I'm new to ScalaFx and want to create a TableView containing an editable Boolean column with CheckBoxs (as well as editable String and Int columns with TextFields). I assume I'll need to use CheckBoxTableCell. I'm using JDK 7u25, ScalaFX 1.0.0-M4/M5 and Scala 2.10.2-final. (I'm not completely certain about the ScalaFX version, but it's definately at least 1.0.0-M5. In any case it's the snapshot Jarek uploaded on August 1 to https://oss.sonatype.org/index.html#nexus-search;quick~scalafx. Jarek only compiles for Scala 2.9.x, but I've downloaded his source code and recompiled it.)

I've already managed to get it halfway working based on Integer Columns in ScalaFX TableView, http://foofighter2146.blogspot.com/2013/06/tutorial-scalafx-slick.html and the scalafx-demo: SimpleTableView. However, I can't use CheckBox's in the TableView and use their values. In stead, I can only get it to work in such a way that I need to type in "true" or "false" to edit the value in the table.

Here's what I have managed to get working thus far:

class Person(firstName_ : String, age_ : Int, cool_ : Boolean) {
  val name = new StringProperty(this, "Name", firstName_)
  val age = new IntegerProperty(this, "Age", age_)
  val cool = new ObjectProperty(this, "Cool", cool)
}

object SimpleEditableTableView extends JFXApp {
  val characters = ObservableBuffer[Person](
    new Person("Peggy", 45, false),
    new Person("Rocky", 43, true)
  )

  stage = new PrimaryStage {
    title = "Simple Ediatble Table View"
    scene = new Scene {
      content = new TableView[Person](characters) {
        editable = true
        columns ++= List(
          new TableColumn[Person, String] {
            text = "Name"
            cellValueFactory = {_.value.name}
            cellFactory = _ => new TextFieldTableCell[Person, String] (new DefaultStringConverter())
            onEditCommit = (evt: CellEditEvent[Person, String]) => {
              val person = evt.rowValue
              val newName = evt.newValue
              println("Here we'll typically save the data. New name = "+newName)
            }
            editable = true
            prefWidth = 180
          },
          new TableColumn[Person, Int] {
            text = "Name"
            cellValueFactory = {_.value.age}
            cellFactory = _ => new TextFieldTableCell[Person, Int] (new IntStringConverter())
            onEditCommit = (evt: CellEditEvent[Person, Int]) => {
              val person = evt.rowValue
              val newAge = evt.newAge
              println("Here we'll typically save the data. New age = "+newAge)
            }
            editable = true
            prefWidth = 180
          },
          new TableColumn[Person, Boolean] {
            text = "Cool"
            cellValueFactory = {_.value.cool}
            cellFactory = _ => new TextFieldTableCell[Person, Boolean] (new BooleanStringConverter())
            onEditCommit = (evt: CellEditEvent[Person, Boolean]) => {
              val person = evt.rowValue
              val newCool = evt.newCool
              println("Here we'll typically save the data. New cool = "+newCool)
            }
            editable = true
            prefWidth = 180
          }
        )
      }
    }
  }
}

For the "Cool" TableColumn, I would like to replace

cellFactory = _ => new TextFieldTableCell[Person, Boolean] (new BooleanStringConverter())

with

val selectedProperty: Int => ObservableValue[Boolean, java.lang.Boolean] = {rowNum: Int => model.characters(rowNum).cool}
cellFactory = column => CheckBoxTableCell.forTableColumn[Person, Boolean](selectedProperty)

in order to get nice CheckBoxes in the TableView (currently, I get TextFields in which I must type out "true" or "false"). However, this gives me the (obvious) error:

type mismatch; found : scalafx.beans.property.ObjectProperty[scala.Boolean] required: scalafx.beans.value.ObservableValue[scala.Boolean,java.lang.Boolean]

and if I change

val selectedProperty: Int => ObservableValue[Boolean, java.lang.Boolean] = {rowNum: Int => model.characters(rowNum).cool}

to val selectedProperty = {rowNum: Int => model.characters(rowNum).cool}

I get one heck of an error message, which basically comes down to the fact that CheckBoxTableCell.forTableColumn[Person, Boolean](selectedProperty) requires selectedProperty to be of type Int => ObservableValue[Boolean, java.lang.Boolean], not Int => ObjectProperty[Boolean]

Was it helpful?

Solution

Basically you should use BooleanProperty, you can find details, including a complete example, in the answer to the same question posted the scalafx-users discussion group https://groups.google.com/d/msg/scalafx-users/oedbP9TY5YE/csNi1qhsNuQJ

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top