JavaFX Tutorials

Monday, September 19, 2016

A Kotlin JavaFX TableView Row Factory with a Lambda

This post applies a Kotlin Lambda to a JavaFX TableView control.


In order to get a TableView action to occur on a double-click, you need to provide a custom Row Factory.  (The default is to respond on a single click). This factory will generate a TableRow with an onMouseClicked handler that checks the clickCount for "2" which indicates a double-click.

There are a few ways to define this RowFactory in Kotlin.  One way, is to use a separate class

class RowFactoryCallback : Callback<TableView<User>, TableRow<User> > {

  override fun call(param: TableView<User>): TableRow<User> {
    val row = TableRow<User>()
    row.onMouseClicked = EventHandler{
        mouseEvent ->
        if( mouseEvent.clickCount == 2 )
            selectItem(row.getItem())
    }
    return row
  }
}

Where the rowFactory assignment is made like this
        
tblUsers.rowFactory = RowFactoryCallback()

And the action taken by the handler is this

fun selectItem(u : User) {
    println("selecting user ${u.email}")
}

Lambda


This can be rewritten to use an anonymous inner class that extends the Callback functional interface.

tblUsers.rowFactory = Callback{
    tbl ->
        val row = TableRow<User>()
        row.onMouseClicked = EventHandler{
            mouseEvent ->
            if( mouseEvent.clickCount == 2 )
                selectItem(row.getItem())
        }
        row
}

Unlike Java, the multi-line Lambda does not require parenthesis.  Also, there is no return required as the final statement.

There is a lot of potential to make single-line functions in Kotlin.  Sometimes, though, you'll need to add in logic that will span more than one programming instruction.  This example used the JavaFX TableView rowFactory as an example of how to create anonymous inner classes (Callback, EventHandler) and to use Lambdas in functions with and without a return value.

No comments:

Post a Comment