• This repository has been archived on 28/Sep/2024
  • Stars
    star
    3,672
  • Rank 12,043 (Top 0.3 %)
  • Language
    Kotlin
  • License
    Apache License 2.0
  • Created almost 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Lightweight JavaFX Framework for Kotlin

TornadoFX Logo

TornadoFX

JavaFX Framework for Kotlin

(This project is no longer maintained)

Travis CI Maven Central Apache License

Important: TornadoFX is not yet compatible with Java 9/10

Oracle is intending to decouple JavaFX from the JDK. We will wait until the decoupled JavaFX is available and stable before upgrading TornadoFX to support it. As of now there is little value and significant effort involved in updating to JDK 9/10, while there will be an enormous value in updating to the decoupled version.

Features

  • Supports both MVC, MVP and their derivatives
  • Dependency injection
  • Type safe GUI builders
  • Type safe CSS builders
  • First class FXML support
  • Async task execution
  • EventBus with thread targeting
  • Hot reload of Views and Stylesheets
  • OSGi support
  • REST client with automatic JSON conversion
  • Zero config, no XML, no annotations

Important version note

TornadoFX requires Kotlin 1.1.2 and jvmTarget 1.8. Make sure you update your IDE plugins (Kotlin + TornadoFX).

After updating IntelliJ IDEA, make sure your Kotlin target version is 1.1 (Project Settings -> Modules -> Kotlin -> Language Version / API Version)

Remember to update your build system to configure the jvmTarget as well.

For Maven, you add the following configuration block to kotlin-maven-plugin:

<configuration>
    <jvmTarget>1.8</jvmTarget>
</configuration>

For Gradle, it means configuring the kotlinOptions of the Kotlin compilation task:

compileKotlin {
    kotlinOptions.jvmTarget= "1.8"
}

Failing to do so will yield errors about the compiler not being able to inline certain calls.

You also need a full rebuild of your code after a version upgrade. If you run into trouble, try to clean caches and restart IDEA (File -> Invalidate caches / Restart).

Getting started

Generate a quickstart application with Maven

mvn archetype:generate -DarchetypeGroupId=no.tornado \
  -DarchetypeArtifactId=tornadofx-quickstart-archetype \
  -DarchetypeVersion=1.7.20

Add TornadoFX to your project

Maven

<dependency>
    <groupId>no.tornado</groupId>
    <artifactId>tornadofx</artifactId>
    <version>1.7.20</version>
</dependency>

Gradle

implementation 'no.tornado:tornadofx:1.7.20'

Snapshots are published to Sonatype

Configure your build environment to use snapshots if you want to try out the latest features:

 <repositories>
   <repository>
     <id>snapshots-repo</id>
     <url>https://oss.sonatype.org/content/repositories/snapshots</url>
     <releases><enabled>false</enabled></releases>
     <snapshots><enabled>true</enabled></snapshots>
   </repository>
 </repositories>

Snapshots are published every day at GMT 16:00 if there has been any changes.

What does it look like? (Code snippets)

Create a View

class HelloWorld : View() {
    override val root = hbox {
        label("Hello world")
    }
}

Start your application and show the primary View and add a type safe stylesheet

import javafx.scene.text.FontWeight
import tornadofx.*

class HelloWorldApp : App(HelloWorld::class, Styles::class)

class Styles : Stylesheet() {
    init {
        label {
            fontSize = 20.px
            fontWeight = FontWeight.BOLD
            backgroundColor += c("#cecece")
        }    
    }    
}

Start app and load a type safe stylesheet

Use Type Safe Builders to quickly create complex user interfaces

class MyView : View() {
    private val persons = FXCollections.observableArrayList(
            Person(1, "Samantha Stuart", LocalDate.of(1981,12,4)),
            Person(2, "Tom Marks", LocalDate.of(2001,1,23)),
            Person(3, "Stuart Gills", LocalDate.of(1989,5,23)),
            Person(3, "Nicole Williams", LocalDate.of(1998,8,11))
    )

    override val root = tableview(persons) {
        column("ID", Person::id)
        column("Name", Person::name)
        column("Birthday", Person::birthday)
        column("Age", Person::age)
        columnResizePolicy = SmartResize.POLICY
    }
}

RENDERED UI

Create a Customer model object that can be converted to and from JSON and exposes both a JavaFX Property and getter/setter pairs:

import tornadofx.getValue
import tornadofx.setValue

class Customer : JsonModel {
    val idProperty = SimpleIntegerProperty()
    var id by idProperty

    val nameProperty = SimpleStringProperty()
    var name by nameProperty

    override fun updateModel(json: JsonObject) {
        with(json) {
            id = int("id") ?: 0
            name = string("name")
        }
    }

    override fun toJSON(json: JsonBuilder) {
        with(json) {
            add("id", id)
            add("name", name)
        }
    }
}

Create a controller which downloads a JSON list of customers with the REST api:

class HelloWorldController : Controller() {
    val api : Rest by inject()
    
    fun loadCustomers(): ObservableList<Customer> = 
        api.get("customers").list().toModel() 
}

Configure the REST API with a base URI and Basic Authentication:

with (api) {
    baseURI = "http://contoso.com/api"
    setBasicAuth("user", "secret")
}

Load customers in the background and update a TableView on the UI thread:

runAsync {
    controller.loadCustomers()
} ui {
    customerTable.items = it
}

Load customers and apply to table declaratively:

customerTable.asyncItems { controller.loadCustomers() }

Define a type safe CSS stylesheet:

class Styles : Stylesheet() {
    companion object {
        // Define css classes
        val heading by cssclass()
        
        // Define colors
        val mainColor = c("#bdbd22")
    }

    init {
        heading {
            textFill = mainColor
            fontSize = 20.px
            fontWeight = BOLD
        }
        
        button {
            padding = box(10.px, 20.px)
            fontWeight = BOLD
        }

        val flat = mixin {
            backgroundInsets += box(0.px)
            borderColor += box(Color.DARKGRAY)
        }

        s(button, textInput) {
            +flat
        }
    }
}

Create an HBox with a Label and a TextField with type safe builders:

hbox {
    label("Hello world") {
        addClass(heading)
    }
    
    textfield {
        promptText = "Enter your name"
    }
}

Get and set per component configuration settings:

// set prefWidth from setting or default to 200.0
node.prefWidth(config.double("width", 200.0))

// set username and age, then save
with (config) {
    set("username", "john")
    set("age", 30)
    save()
}

Create a Fragment instead of a View. A Fragment is not a Singleton like View is, so you will create a new instance and you can reuse the Fragment in multiple ui locations simultaneously.

class MyFragment : Fragment() {
    override val root = hbox {
    }
}

Open it in a Modal Window:

find<MyFragment>().openModal()

Lookup and embed a View inside another Pane in one go

add<MyFragment>()

Inject a View and embed inside another Pane

val myView: MyView by inject()
 
init {
    root.add(myFragment)
}

Swap a View for another (change Scene root or embedded View)

button("Go to next page") {
    action {
        replaceWith<PageTwo>(ViewTransition.Slide(0.3.seconds, Direction.LEFT)
    }
}

Open a View in an internal window over the current scene graph

button("Open") {
    action {
        openInternalWindow<MyOtherView>()
    }
}

More Repositories

1

fxlauncher

Auto updating launcher for JavaFX Applications
Java
714
star
2

tornadofx-samples

Samples and best practices for TornadoFX
Kotlin
193
star
3

tornadofx2

TornadoFX 2.0
Kotlin
155
star
4

tornadofx-guide

TornadoFX Guide
134
star
5

tornadofx-controls

CSS Stylable Controls for JavaFX
Java
106
star
6

tornadofx-idea-plugin

TornadoFX Plugin for IntelliJ IDEA
Kotlin
72
star
7

tornadofx-controlsfx

ControlsFX Builder extensions and utilities for TornadoFX
Kotlin
71
star
8

todomvc

TodoMVC with TornadoFX
Kotlin
51
star
9

kdbc

SQL DSL for Kotlin
Kotlin
44
star
10

fxldemo

FXLauncher demo application
Java
41
star
11

fxldemo-gradle

FXLauncher demo for Gradle
Java
22
star
12

fxlauncher-gradle-plugin

Gradle plugin for FXLauncher
Groovy
20
star
13

calculator

Calculator written in TornadoFX (JavaFX + Kotlin)
Kotlin
18
star
14

github-browser

TornadoFX GitHub Browser - demo/showcase app
Kotlin
14
star
15

tooldb

Cutting Tool Database - JDBC demo for TornadoFX
Kotlin
8
star
16

tornadofx-kitchensink

TornadoFX Kitchensink Samples
Kotlin
8
star
17

epp-verisign

Verisign EPP Bundle with modifications and bugfixes to support NORID and RRPProxy
Java
7
star
18

tornadofx-web

tornadofx.io web page
CSS
5
star
19

javafx-osgi

JavaFX 8.0 OSGi bundle to support JavaFX in an OSGi container
5
star
20

tornadofaces

Modern JSF Component Framework
Java
4
star
21

tornadofx-hibernate-demo

TornadoFX Hibernate Integration Demo
Kotlin
4
star
22

tornadofx-android-compat

Initial commit
Java
4
star
23

tornadofx-quickstart-archetype

Initial commit
Kotlin
3
star
24

libsass-filter

Compiles SASS to CSS on-the-fly
Java
3
star
25

fxlauncher-custom-ui

Demo project showing how to customize the FXLauncher update UI.
Java
3
star
26

tornadofx-charts

TornadoFX Bindings for Hansolo's excellent chart library
Kotlin
3
star
27

kdbc-examples

Examples for KDBC
Kotlin
2
star
28

tornadofx-controls-sampler

TornadoFX Controls Sampler Application
Java
2
star
29

interapp

Dynamic, Modular Microservices with Java EE
Java
2
star
30

dyndns

Tornado DynDNS Client uses the standard DNS protocol to perform dynamic DNS updates
Java
2
star
31

ahkpok3r

AutoHotKey Script to turn any keyboard into a POK3R (Arrow Keys, PgUp/PgDn/Home/End/Ins/Del)
AutoHotkey
2
star
32

edmacs

Edvin's Emacs configuration
Emacs Lisp
1
star
33

tornadofx-java

Deprecated, see tornadofx!
Java
1
star
34

tornadokeyboard-userstore

Kotlin
1
star