bekwam courses

TornadoFX Cut, Copy, and Paste with Kotlin Lambdas

August 8, 2018

Cut, Copy, and Paste are standard functions for any application that uses TextFields or other types of TextInputControls like TextAreas. In this demo I cover a generalized use of these functions using Kotlin lambdas in TornadoFX.

My app consists of a MenuBar and a Form with three fields, two TextField and one TextArea. Inside of the MenuBar there is an edit Menu containing the functions Cut, Copy, and Paste. When text is entered and highlighted, it can be cut or copied from the text input. By clicking into another field, the contents of the old TextField can be pasted into the new field.

Cut, Copy, and Paste in Action

Video showing the use of the cut, copy, and paste buttons (no sound).

Here is the code for the app in the video shown above:


class CutCopyPasteDemoView : View("Cut, Copy, Paste") {

    fun clipOps(scene : Scene, op : (TextInputControl) -> Unit) {
        val focusedOwner = scene.focusOwner
        if( focusedOwner is TextInputControl) {
            op(focusedOwner)
        }
    }

    override val root = vbox {

        menubar {
            menu("Edit") {
                item("Copy") {
                    action {
                        clipOps( scene) { it.copy() }
                    }
                }
                item("Cut") {
                    action {
                        clipOps( scene) { it.cut() }
                    }
                }
                item("Paste") {
                    action {
                        clipOps( scene) { it.paste() }
                    }
                }
            }
        }

        form {
            fieldset {
                field("TF1") {
                    textfield()
                }
                field("TF2") {
                    textfield()
                }
                field("TF3") {
                    textarea()
                }
            }
        }
    }
}

class CutCopyPasteDemo : App(CutCopyPasteDemoView::class)

fun main(args: Array<String>) {
    launch<CutCopyPasteDemo>(args)
}
	

Kotlin Lambdas

Attached to each item in the MenuBar is an action. Inside of each action is a single, generalized function clipOps that accepts a Scene and a function as its parameters. The scene that is passed into the function is always the current scene. The part of the scene where the cursor currently lies (or in the cut/copy case, the highlighted area) is then stored in the val focusedOwner. If focusedOwner is a textInputControl then the function passed in as the second parameter is called with the input as a parameter. In the case of this app that function will be cut(), copy(), or paste() imported from javafx.scene.control. The way that these functions are used is unique to Kotlin. Initially, the function clipOps() is called with only the scene passed in as a parameter (clipOps(scene)). The function call is followed by curly braces containing the line it.foo(). It refers to the specified textInputControl and foo() to the function being applied.

The use of lambdas makes the code simpler, cleaner, and easier to read. The syntactical brevity of Kotlin is one of its many advantages over other languages such as Java.


By Rob Walker

Software Engineer at Bekwam, Inc