Code Monkey home page Code Monkey logo

tornadofx's Introduction

TornadoFX Logo

TornadoFX

Lightweight JavaFX Framework for Kotlin

Travis CI Maven Central Apache License

Features

  • Dependency injection
  • Type safe builders
  • Async task execution
  • MVC
  • Extremely light weight
  • Small, easy to grasp API
  • REST client with automatic JSON conversion
  • Zero config, no XML, no annotations

Getting started

Generate a quickstart application with Maven

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

Add TornadoFX to your project

Maven

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

Gradle

compile 'no.tornado:tornadofx:1.4.1'

What does it look like? (Code snippets)

Create a View

class HelloWorld : View() {
	override val root = HBox(Label("Hello world")) 
}

Load the root node from HelloWorld.fxml and inject controls by fx:id

class HelloWorld : View() {
	override val root: HBox by fxml()
	val myLabel: Label by fxid()
	
	init {
		myLabel.text = "Hello world"
	}
}

Start your application and show the primary View by extending the App class

class HelloWorldApp : App {
	override val primaryView = HelloWorld::class

	init {
		importStylesheet("/styles.css")
	}
}

Start app and load a stylesheet

Use Type Safe Builders to quickly create complex user interfaces

class MyView : View() {

    override val root = VBox()

    private val persons = FXCollections.observableArrayList<Person>(
            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))
    )

    init {
        with(root) {
            tableview<Person> {
                items = persons
                column("ID", Person::id)
                column("Name", Person::name)
                column("Birthday", Person::birthday)
                column("Age", Person::age)
            }
        }
    }
}

RENDERED UI

Create a Customer model object that can be converted to and from JSON and complies with JavaFX Property guidelines:

class Customer : JsonModel {
    var id by property<Int>()
    fun idProperty() = getProperty(Customer::id)

    var name by property<String>()
    fun nameProperty() = getProperty(Customer::name)

    override fun updateModel(json: JsonObject) {
        with(json) {
            id = int("id")
            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:

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

Load customers and apply to table declaratively:

customerTable.asyncItems { controller.loadCustomers() }

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 Viewis, so you will create a new instance via the constructor and you can reuse the Fragment in multiple ui locations simultaneously.

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

Open it in a Modal Window:

MyFragment().openModal()

Lookup and embed a View inside another Pane in one go

root += MyFragment::class

Inject a View and embed inside another Pane

val myView: MyView by inject()
 
init {
	root += myFragment
}

tornadofx's People

Contributors

hastebrot avatar kiskae avatar picoworm avatar ronsmits avatar ruckustboom avatar thomasnield avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.