Kotlin JavaFX - ListView - Fill From Array

April 18, 2018 Oclemy JavaFX ListView, Kotlin Array 4 minutes, 44 seconds

JavaFX is now the number one GUI toolkit for creating rich graphical java applications.

It allows us create graphical user interfaces programmatically using predefined classes in an object oriented manner.

In this tutorial we look at how to populate a JavaFX ListView from an array. We then show a JavaFX dialog when an item is selected from the JavaFX ListView.

You can check our YouTube video right here:

Here's our code:

package info.camposha

import javafx.application.Application
import javafx.geometry.Insets
import javafx.geometry.Pos
import javafx.scene.Group
import javafx.scene.Scene
import javafx.scene.control.Alert
import javafx.scene.control.Label
import javafx.scene.control.ListView
import javafx.scene.layout.VBox
import javafx.scene.text.Font
import javafx.stage.Stage
import java.lang.Exception
import java.util.*

class Neb : Application() {

    internal var mListView = object
    /*
    Construct JavaFX UI
     */
    @Throws(Exception::class)
    override fun start(stage: Stage) {
        val scene = Scene(Group())
        stage.title = "Kotlin JavaFX : ListView - Fill From Array"
        stage.width = 550.0
        stage.height = 550.0

        val titleLabel = Label("Kotlin Array of Nebulas")
        titleLabel.font = Font("Lucida", 20.0)

        val listview = ListView<Any>()
        mListView=listview

        populateData()
        handleItemClicks()

        val vbox = VBox()
        vbox.spacing = 5.0
        vbox.padding = Insets(10.0, 0.0, 0.0, 10.0)
        vbox.children.addAll(titleLabel, listview)
        vbox.alignment = Pos.CENTER

        val group = scene.root as Group
        group.children.add(vbox)
        group.layoutX = 100.0

        stage.scene = scene
        stage.show()
    }

    /*
    Populate ListView with ArrayList data
     */
    private fun populateData()
    {
        val nebulae = arrayOf("Horse Head", "Black Widow", "Ghost Head", "Cat's Eye", "Elephant's Trunk", "Helix", "Rosette", "Snake", "Bernad 68", "Ant", "Orion", "Butterfly", "Eagle", "Own", "Ring", "Pelican", "Cone", "Flame", "Witch Head", "Bumerang")
        val lv:ListView<Any> = mListView as ListView<Any>
        for (nebular in nebulae) {
            lv.items.add(nebular)
        }

    }
    /*
     Handle ListView itemClicks
     */
    private fun handleItemClicks() {
        val lv:ListView<Any> = mListView as ListView<Any>
        lv.setOnMouseClicked({
            val selectedItem = lv.selectionModel.selectedItem.toString()
            val d = Alert(Alert.AlertType.INFORMATION, selectedItem)
            d.show()
        })
    }
    /*
    Launch application
     */
    fun go(args:Array<String>)
    {
        Application.launch(*args)
    }
    companion object {
        /*
         Main method
       */
        @JvmStatic fun main(args: Array<String>) {
            Neb().go(args)
        }
    }
}

Explanation

First we specify our imports using the import statement. Mostof our imports are from javafx.scene package.

Create JavaFX Application

We will create our class and make it derive from javafx.application.Application package:

class Neb : Application(){..}

We will have an instance field initialized to an object:

internal var mListView = object

Override the start() method

We will then override the start() method defined in the javafx.application.Application package:

override fun start(stage: Stage)

That function is taking in a javafx.stage.Stage object. This will be the primary stage of the application.

Our start() method will be throwing ajava.lang.Exception so we decorate it with the @Throws(Exception::class) attribute.

First we will instantiate the javafx.scene.Scene object, passing it a javafx.scene.Group object:

val scene = Scene(Group())

Set JavaFX stage properties

Then set the title,width and height properties of the stage object:

stage.title = "Kotlin JavaFX : ListView - Fill From Array"
stage.width = 550.0
stage.height = 550.0

Create JavaFX Label and set custom Font

We will instantiate the javafx.scene.control.Label object, set its text property via the constructor and set the Label Font:

    val titleLabel = Label("Kotlin Array of Nebulas")
    titleLabel.font = Font("Lucida", 20.0)

Instantiate JavaFX ListView

Then instantiate our javafx.scene.control.ListView and assign it to the instance field we had defined earlier on:

val listview = ListView<Any>()
mListView=listview

We will then invoke the populateData() and handleItemClicks() methods:

populateData()
handleItemClicks()

Create VBox and set its properties

Next we will instantiate a javafx.scene.layout.VBox, set its spacing, padding, children and alignment:

        val vbox = VBox()
        vbox.spacing = 5.0
        vbox.padding = Insets(10.0, 0.0, 0.0, 10.0)
        vbox.children.addAll(titleLabel, listview)
        vbox.alignment = Pos.CENTER

Add VBox to Group

Then obtain the javafx.scene.layout.Group reference, add it our vbox and set the layoutX property:

        val group = scene.root as Group
        group.children.add(vbox)
        group.layoutX = 100.0

Set JavaFX Scene to primary Stage and show Stage

Then set the stage to our scene and show the stage via the show() method:

        stage.scene = scene
        stage.show()

Create a Kotlin Array and populate it with data

Next we will create an array in kotlin using the arrayOf() method:

val nebulae = arrayOf("Horse Head", "Black Widow", "Ghost Head", "Cat's Eye", "Elephant's Trunk", "Helix", "Rosette", "Snake", "Bernad 68", "Ant", "Orion", "Butterfly", "Eagle", "Own", "Ring", "Pelican", "Cone", "Flame", "Witch Head", "Bumerang")

Convert our Object to ListView

Then cast our mListView object to a ListView using the as operator:

        val lv:ListView<Any> = mListView as ListView<Any>

Loop though Kotlin Array and add items to JavaFX ListView

Then loop through the array filling and fill our javafx ListView with items from the kotlin array:

        for (nebular in nebulae) {
            lv.items.add(nebular)
        }

JavaFX ListView Selected ItemClicks handling

We want to handle the itemClicks for the ListView. So we will us the setOnMouseClicked() event handler:

        val lv:ListView<Any> = mListView as ListView<Any>
        lv.setOnMouseClicked(..)

Then get the selected item from the selectionModel and casting it to a string:

val selectedItem = lv.selectionModel.selectedItem.toString()

Create a JavaFX Alert and show selected item

In the javafx.scene.control package is defined an Alert class that we can use to show alert dialogs or modals.

So we instantiate the Alert class, passing it the selected item:

val d = Alert(Alert.AlertType.INFORMATION, selectedItem)

and call show to show the javafx dialog:

d.show()

Launch the JavaFX application

We will then launch our JavaFX application:

fun go(args:Array<String>)
    {
        Application.launch(*args)
    }
    companion object {
        /*
         Main method
       */
        @JvmStatic fun main(args: Array<String>) {
            Neb().go(args)
        }
    }

Best Regards.

Comments