Coder Social home page Coder Social logo

tornadofx's Introduction

TornadoFX Logo

TornadoFX

Lightweight JavaFX Framework for Kotlin

Travis CI Maven Central Apache License

Features

  • Supports both MVC, MVP and their derivatives
  • Dependency injection
  • Type safe GUI builders
  • First class FXML support
  • Type safe CSS builders
  • Async task execution
  • Hot reload of Views and Stylesheets
  • Strong OSGi support
  • 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.5.8

Add TornadoFX to your project

Maven

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

Gradle

compile 'no.tornado:tornadofx:1.5.8'

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 and add a type safe stylesheet

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")
            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::class).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
}

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

button("Go to next page") {
    setOnAction {
    	replaceWith(PageTwo::class, ViewTransition.Slide(0.3.seconds, Direction.LEFT)
    }
}

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

button("Open") {
    setOnAction {
        openInternalWindow(MyOtherView::class)
    }
}

tornadofx's People

Contributors

bekwam avatar hastebrot avatar hsyed avatar jcornaz avatar kiskae avatar luleyleo avatar mitchclay avatar pg5 avatar picoworm avatar polmabri avatar ronsmits avatar ruckustboom avatar thomasnield avatar

Watchers

 avatar  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.