bekwam courses

Replacing Views in TornadoFX

April 18, 2018

This article presents a TornadoFX program that navigates through a pair of Views to simulate a login operation. First, a LoginView is presented in a 320x480 window. When the user is logged-on, as simulated by a button press, the app transitions to a larger 1024x768 MainView. If the user logs out, they are presented with the LoginView again, but the screen size of MainView is retained.

The navigation is implemented with the TornadoFX replaceWith() function. This function is called on an existing View with optional resize and fade arguments to move to a different View.

In the sample program, the initial LoginView screen size is set by the createPrimaryScene() of the App class. The MainView is displayed and the onDock() function sets up a new window size. When the user presses the Logout button of the MainView, the original LoginView is displayed but since the replaceWith() does not specify sizeToScreen=true, the LoginView uses the new MainView size of 1024x768.

Screenshot of the Three Views and Their Screen Sizes
Navigating Different Views and Screen Sizes

This sample program initializes a three-element List and displays the names as a comma-separated String in a Label. To demonstrate the dynamic nature of Binding, a Button is added that will add items to the List. When an item is added, the String expression in the Label is automatically updated.

The class begins with a domain object, Person. Person has a single field "name".

This is code from a Kotlin file ReplaceWithApp.kt.

	
class ReplaceWithApp : App(LoginView::class) {
  override fun createPrimaryScene(view: UIComponent) = Scene(view.root, 320.0, 480.0)
}

class LoginView : View("Login") {

  override val root = vbox {
    button("Login") {
      setOnAction {
        this@LoginView.replaceWith(MainView::class,
          transition = ViewTransition.FadeThrough(1.seconds))
      }
    }
  }
}

class MainView : View("Main") {
  override val root = vbox {
    label("Main Content Here")
    hyperlink( "Logout") {
      setOnAction {
        this@MainView.replaceWith(LoginView::class,
        transition = ViewTransition.FadeThrough(1.seconds))
      }
    }
  }
  override fun onDock() {
    primaryStage.width = 1024.0
    primaryStage.height = 768.0
  }
}

fun main(args : Array<String>) {
  Application.launch(ReplaceWithApp::class.java)
}

replaceWith() is a convenient way to navigate between two Views in TornadoFX. While desktop apps often make use of popup dialogs, this technique can often be more productive as a smart UI can dispense with the extra window closing operations and position changing sets of controls directly under the cursor and keyboard of the user.


Headshot of Carl Walker

By Carl Walker

President and Principal Consultant of Bekwam, Inc