CS 346 (W23)
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage


How-to questions for building desktop applications with Kotlin and JavaFX.

Create a simple windowed application

See the JavaFX lectures, and the public samples under 03.JavaFX

To create a JavaFX application, you need to derive your top-level class from Application, and override the start method. The stage that is passed into this method by the framework is an abstraction of the window itself.

import javafx.application.Application
import javafx.stage.Stage

class Main : Application() {
	override fun start(stage: Stage) {
  	// set window parameters
    stage.title = "Window title"
    // display it

Support (or prevent) window resizing

Set the stage properties related to window sizing.

stage.isResizable = true

// provide range for width
stage.width = 800.0
stage.width = 800.0
stage.minWidth = 400.0
stage.maxWidth = 1200.0

// provide range for height
stage.height = 400.0
stage.minHeight = 200.0
stage.maxHeight = 800.0

Add widgets to the screen

See the Widget lectures and the public samples under 06.Widgets.

Determine which widgets you need on the screen, and then create a layout, which describes how you want them positioned (see JavaFX - Layout).

// use a VBox to stack 2 buttons vertically
val vbox = VBox()
val button1 = Button("One")
val button2 = Button("Two")
vbox.children.addAll(button1, button2)

// add layout to a scene
val scene = Scene(vbox)

// add scene to the stage
stage.scene = scene

Add a menubar with keyboard shortcuts

See the Widget lectures and the public samples under 06.Widgets.

You need three classes: MenuBar, Menu and MenuItem. e.g. a typical menu would include File (Menu), with drop-down menus for New, Open, and so on (MenuItems).

Here’s an example of setting up a File menu with a Quit menu item that exits the application.

val menuBar = MenuBar()
val fileMenu = Menu("File")
val fileQuit = MenuItem("Quit")

// activating Quit menu exits the application
fileQuit.setOnAction { Platform.exit() }

// Ctrl-Q will also activate the Quit menu item
fileQuit.accelerator = KeyCodeCombination(KeyCode.Q, KeyCombination.CTRL_DOWN)

// assemble together; the menu still needs to be added to a layout

Handle input from a widget

See the Events lectures and the public samples under 05.Events.

See JavaFX - Event Handlers. You need to add a handler to a widget, telling it what code to execute when the user activates that widget.

// mouse events
val delButton = Button("Delete")
delButton.setOnMouseClicked { event -> deleteSelectedFile() }

// keyboard events 
val input = TextField()
input.setOnKeyPressed { event ->
	when (event.code) {
   	KeyCode.ENTER -> processInput()

Collect information in a dialog box

You have a couple of choices:

  1. You can create a new Stage containing a custom layout that you create, and show it to collect data. For something complex (e.g. preferences dialog) this may be required.
  2. For very simple input, JavaFX has dialog box classes.

Here’s an example of how to collect a single text value in a dialog.

val td = TextInputDialog()
td.title = "Title"
td.headerText = "Enter new value:"
// the app will block here until the user enters a value
val value:String = td.editor.text

Add an Image to a Button (or other widget)

You need to place an appropriately-sized image in the src/resources/ folder of your project, and then you can reference them directly in code.

This works best with PNG files, sized to roughly 20x20.

val renameButton = Button("Rename")
renameButton.graphic = ImageView(Image("rename.png"))

Play a sound clip

This is useful if you want audio feedback from the interaction e.g. button “clicks”.

Here’s a click handler for a button that plays a sound when the button is pressed. The file click.mp3 should be placed in the src/resources folder.

val button = Button("Click Here")
button.setOnMouseClicked {
  val sound = javaClass.classLoader.getResource("click.mp3").toString()
  val clip = AudioClip(sound)