### Basic Workspace Setup Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Workspaces.html To start a Workspace application, subclass `App` and set the primary `View` to `Workspace::class`. ```kotlin class MyApp : App(Workspace::class) ``` -------------------------------- ### TornadoFX Application Setup Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/6_CSS.html Basic TornadoFX application setup, including the main App class and view. Ensures styles are reloaded on focus for development. ```kotlin import javafx.scene.layout.VBox import tornadofx.* class MyApp: App(MyView::class, MyStyle::class) { init { reloadStylesheetsOnFocus() } } ``` ```kotlin class MyView: View() { override val root = vbox { button("Press Me") button("Press Me Too") } } ``` -------------------------------- ### Controller Output Example Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html This is an example of the console output when the 'Commit' button is clicked in the preceding View. ```text Writing Alpha to database! ``` -------------------------------- ### StackPane Layout Example Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/7_Layouts_and_Menus.html Demonstrates a StackPane layout where elements are stacked on top of each other. The order of declaration determines the stacking order from bottom to top. ```kotlin class MyView: View() { override val root = stackpane { button("BOTTOM") { useMaxHeight = true useMaxWidth = true style { backgroundColor += Color.AQUAMARINE fontSize = 40.0.px } } button("TOP") { style { backgroundColor += Color.WHITE } } } } ``` -------------------------------- ### View with Controller for Data Provision Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Controllers can provide data to a View. This example shows a View displaying a list of items managed by the Controller. ```kotlin import javafx.collections.FXCollections import tornadofx.* class MyView : View() { val controller: MyController by inject() override val root = vbox { label("My items") listview(controller.values) } } class MyController: Controller() { val values = FXCollections.observableArrayList("Alpha","Beta","Gamma","Delta") } ``` -------------------------------- ### Open App in Fullscreen on Startup Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Layout_Debugger.html Override the start method in your App class to make the application launch in fullscreen mode. This sets the primary stage to fullscreen. ```kotlin class MyApp : App(MyView::class) { override fun start(stage: Stage) { super.start(stage) stage.isFullScreen = true } } ``` -------------------------------- ### Launch TornadoFX Application with Main Function Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Provide a package-level `main` function to launch the TornadoFX application, especially when command-line arguments are needed. The `launch()` function starts the application. ```kotlin fun main(args: Array) { launch(args) } ``` -------------------------------- ### Define TornadoFX Application Entry Point Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Extend the `App` class to create your application's entry point and specify the initial `View` as a constructor argument. This class serves as the application's starting point. ```kotlin import tornadofx.* class MyApp: App(MyView::class) ``` -------------------------------- ### Load Customers using GET Request Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/JSON_and_REST.html Performs a GET request to the 'customers' endpoint and converts the JSON response list to a list of Customer models. The type argument for `toModel` can be inferred from the return type or specified explicitly. ```kotlin class CustomerController : Controller() { val api: Rest by inject() fun loadCustomers(): ObservableList = api.get("customers").list().toModel() } ``` ```kotlin fun loadCustomers() = api.get("customers").list().toModel() ``` -------------------------------- ### Explicitly Connect Workspace Actions Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Workspaces.html An example demonstrating how to explicitly connect workspace actions by overriding properties and methods. This approach is generally not recommended and is shown for understanding the proxy mechanism. ```kotlin class TooExplicitCustomerEditor : View() { override val root = tab { ... } override val savable = root.savable override val refreshable = root.refreshable override val deletable = root.deletable override fun onSave() { root.onSave() } override fun onDelete() { root.onDelete() } override fun onRefresh() { root.onRefresh() } } ``` -------------------------------- ### Docking a View in Workspace Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Workspaces.html Dock a component into the Workspace's content area by calling `workspace.dock()` on it. This example docks a `CustomerList` component when the application starts. ```kotlin class MyApp : App(Workspace::class) { override fun onBeforeShow(view: UIComponent) { workspace.dock() } } ``` -------------------------------- ### Save Application Preferences Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Config_Settings_and_State.html Use the `preferences` helper to store application-wide settings. This example demonstrates saving a boolean and a string value. ```kotlin preferences("application") { putBoolean("boolean", true) putString("String", "a string") } ``` -------------------------------- ### Creating UI with Builders Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Use builders to define UI layout and elements. This example creates a simple form with labels, text fields, and a login button. ```kotlin var firstNameField: TextField by singleAssign() var lastNameField: TextField by singleAssign() override val root = vbox { hbox { label("First Name") firstNameField = textfield() } hbox { label("Last Name") lastNameField = textfield() } button("LOGIN") { useMaxWidth = true action { println("Logging in as ${firstNameField.text} ${lastNameField.text}") } } } } ``` -------------------------------- ### Login Screen with Config Storage Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Config_Settings_and_State.html This example demonstrates a login screen that stores username and password in the view-specific config object. It uses TornadoFX type-safe builders for the UI and saves credentials upon successful login. Note: This is illustrative and not recommended for sensitive data. ```kotlin class LoginScreen : View() { val loginController: LoginController by inject() val username = SimpleStringProperty(this, "username", config.string("username")) val password = SimpleStringProperty(this, "password", config.string("password")) override val root = form { fieldset("Login") { field("Username:") { textfield(username) } field("Password:") { textfield(password) } buttonbar { button("Login").action { runAsync { loginController.tryLogin(username.value, password.value) } ui { success -> if (success) { with(config) { set("username" to username.value) set("password" to password.value) save() } showMainScreen() } } } } } } fun showMainScreen() { // hide LoginScreen and show the main UI of the application } } ``` -------------------------------- ### Bootstrap TornadoFX from Swing Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Integration.html Start a TornadoFX application within an existing Swing application. This involves initializing the JavaFX toolkit and then running the TornadoFX application on the JavaFX Platform. ```java public class SwingApp { private static void createAndShowGUI() { // initialize toolkit JFXPanel wrapper = new JFXPanel(); // Init TornadoFX Application Platform.runLater(() -> { Stage stage = new Stage(); MyApp app = new MyApp(); app.start(stage); }); } public static void main(String[] args) { SwingUtilities.invokeLater(SwingApp::createAndShowGUI); } } ``` -------------------------------- ### Application Class for Tabbed Workspace Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Workspaces.html Specify the TabbedWorkspace as the starting point for a TornadoFX application. ```kotlin class TabbedWorkspaceApp : App(TabbedWorkspace::class) ``` -------------------------------- ### Concise TableView Declaration Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/1_Why_TornadoFX.html This is a focused example of declaring a TableView with columns, highlighting the minimal code required by TornadoFX for UI construction. ```kotlin tableview(persons) { column("ID", Person::idProperty) column("Name", Person::nameProperty) column("Birthday", Person::birthdayProperty) readonlyColumn("Age", Person::age) } ``` -------------------------------- ### Create BubbleChart Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/8_Charts.html BubbleChart is similar to ScatterPlot but includes a third variable to control the radius of each point. This example shows machine capacity by output/week, with bubble radii reflecting the number of machines used. ```kotlin bubblechart("Machine Capacity by Output/Week", NumberAxis(), NumberAxis()) { series("Product X") { data(1,24,1) data(2,46,2) data(3,23,1) data(4,27,2) data(5,18,1) } series("Product Y") { data(1,12,1) data(2,31,2) data(3,9,1) data(4,11,1) data(5,15,2) } } ``` -------------------------------- ### Retrieve Application Preferences Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Config_Settings_and_State.html Retrieve previously saved preferences using the `preferences` helper. Provide a default value for `get` and `getBoolean` if the key might not exist. ```kotlin var bool: Boolean = false var str: String = "" preferences("test app") { bool = getBoolean("boolean key", false) str = get("string", "") } ``` -------------------------------- ### Manually Handle Dynamic Views in a TabPane Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/OSGi.html This example demonstrates manual control over embedding dynamic views. It checks the discriminator and explicitly creates a new tab for the view if it matches 'dashboard', returning false to prevent automatic addition. ```kotlin tabPane.addViewsWhen { if (it.discriminator == "dashboard") { val view = it.getView() tabPane.tab(view.title, view.root) } false } ``` -------------------------------- ### Basic Drawer Implementation Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/7_Layouts_and_Menus.html Demonstrates a basic Drawer with three items: Screencasts, Links, and People. Each item displays different content types like a webview, a listview, and a tableview. Ensure sample data and URIs are defined. ```kotlin class DrawerView : View("TornadoFX Info Browser") { override val root = drawer { item("Screencasts", expanded = true) { webview { prefWidth = 470.0 engine.userAgent = iPhoneUserAgent engine.load(TornadoFXScreencastsURI) } } item("Links") { listview(links) { cellFormat { link -> graphic = hyperlink(link.name) { setOnAction { hostServices.showDocument(link.uri) } } } } } item("People") { tableview(people) { column("Name", Person::name) column("Nick", Person::nick) } } } class Link(val name: String, val uri: String) class Person(val name: String, val nick: String) // Sample data variables left out (iPhoneUserAgent, TornadoFXScreencastsURI, people and links) } ``` -------------------------------- ### Opening the Customer Wizard Modally Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Wizard.html Demonstrates how to instantiate and open the CustomerWizard as a modal dialog from a button's action. This is a common pattern for initiating wizard-based workflows. ```kotlin button("Add Customer").action { find { openModal() } } ``` -------------------------------- ### Applying Nested Styles in a View Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/6_CSS.html Apply the 'critical' CSS class to an HBox and observe how the nested styles affect the buttons within it. The HBox gets an orange border, and the buttons inside get a red background and white text. ```kotlin class MyApp: App(MyView::class, MyStyle::class) { init { reloadStylesheetsOnFocus() } } class MyView: View() { override val root = hbox { addClass(MyStyle.critical) button("Warning!") button("Danger!") } } ``` -------------------------------- ### Create an Arc with TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/9_Shapes_and_Animation.html Constructs an arc with specified center, radii, start angle, length, and type (e.g., ROUND). ```kotlin arc { centerX = 200.0 centerY = 200.0 radiusX = 50.0 radiusY = 50.0 startAngle = 45.0 length = 250.0 type = ArcType.ROUND } ``` -------------------------------- ### Application Startup with Spring Context Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Dependency_Injection.html Initialize the Spring `ApplicationContext` in the `init` block of your `App` class and hook it into TornadoFX via `FX.dicontainer`. ```kotlin class SpringExampleApp : App(SpringExampleView::class) { init { val springContext = ClassPathXmlApplicationContext("beans.xml") FX.dicontainer = object : DIContainer { override fun getInstance(type: KClass): T = springContext.getBean(type.java) } } } ``` -------------------------------- ### Create a Themed ListMenu Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/7_Layouts_and_Menus.html Demonstrates creating a ListMenu with a 'blue' theme and custom icons. The 'whenSelected' block can be used to define actions for each item. ```kotlin listmenu(theme = "blue") { item(text = "Contacts", graphic = Styles.contactsIcon()) { // Marks this item as active. activeItem = this whenSelected { /* Do some action */ } } item(text = "Projects", graphic = Styles.projectsIcon()) item(text = "Settings", graphic = Styles.settingsIcon()) } ``` -------------------------------- ### Customizing Validation Trigger Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/11_Editing_Models_and_Validation.html Shows how to specify a `ValidationTrigger` for the `required` validator, such as `OnBlur`, to control when validation is performed. This example applies `OnBlur` to a `textfield`. ```kotlin textfield(username).required(ValidationTrigger.OnBlur) ``` -------------------------------- ### Define Person Data Class Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/5_Data_Controls.html Defines a simple data class 'Person' with name and department properties, used for populating TreeView examples. ```kotlin data class Person(val name: String, val department: String) val persons = listOf( Person("Mary Hanes","Marketing"), Person("Steve Folley","Customer Service"), Person("John Ramsy","IT Help Desk"), Person("Erlick Foyes","Customer Service"), Person("Erin James","Marketing"), Person("Jacob Mays","IT Help Desk"), Person("Larry Cable","Customer Service") ) ``` -------------------------------- ### Add a TextField with Initial Text and Listener Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Create a TextField with initial text and attach a listener to its `textProperty()` to react to text changes. ```kotlin textfield("Input something") { textProperty().addListener { obs, old, new -> println("You typed: " + new) } } ``` -------------------------------- ### Define WeeklyReport Data Class Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/5_Data_Controls.html A sample data class representing a weekly report with a method to get total sales for a specific day. ```kotlin abstract class WeeklyReport(val startDate: LocalDate) { abstract fun getTotal(dayOfWeek: DayOfWeek): BigDecimal } ``` -------------------------------- ### Get Reference to Table Row Expander Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/5_Data_Controls.html Obtain a reference to the row expander for programmatic manipulation. This is useful for controlling visibility or toggling expansion states. ```kotlin val expander = rowExpander(true) { ... } ``` -------------------------------- ### Lookup Component Instance with `find` Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Dependency_Injection.html Use `find` to retrieve a component instance from the global registry. If the component does not exist, it will be created. ```kotlin val myController = find(MyController::class) ``` -------------------------------- ### Create a PieChart with an ObservableList Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/8_Charts.html Initialize a `PieChart` using a pre-defined `ObservableList`. This is useful when data is prepared separately. ```kotlin val items = listOf( PieChart.Data("Windows", 77.62), PieChart.Data("OS X", 9.52), PieChart.Data("Other", 3.06), PieChart.Data("Linux", 1.55), PieChart.Data("Chrome OS", 0.55) ).observable() piechart("Desktop/Laptop OS Market Share", items) ``` -------------------------------- ### Load Resource URL with resources Helper Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Use the `resources` helper object within a `Component` to get the external form URL of a resource file. ```kotlin val myAudiClip = AudioClip(resources["mysound.wav"]) ``` -------------------------------- ### Configuring Drawer Side and Multiselect Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/7_Layouts_and_Menus.html Shows how to configure the Drawer to display buttons on the right side and enable multiselect mode. The `showHeader` parameter controls the appearance of a header when multiselect is enabled. ```kotlin drawer(side = Side.RIGHT, multiselect = true) { // Everything else is identical } ``` -------------------------------- ### Populate View with UI Controls Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Use the initializer block within a `View` to add UI elements like `Button` and `Label` to the `root` node. Ensure the `tornadofx.*` import is present for advanced extension functions. ```kotlin import tornadofx.* class MyView: View() { override val root = vbox { button("Press me") label("Waiting") } } ``` -------------------------------- ### Replace View with Transition in TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Swap the current view with another using `replaceWith`, optionally specifying a transition animation. This example shows a slide transition. ```kotlin replaceWith(MyView1::class, ViewTransition.Slide(0.3.seconds, ViewTransition.Direction.LEFT)) ``` -------------------------------- ### Dynamic ProgressBar Simulation Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Simulate progress updates in a ProgressBar over time using a background thread and Platform.runLater for UI updates. This demonstrates dynamic progress visualization. ```kotlin progressbar { thread { for (i in 1..100) { Platform.runLater { progress = i.toDouble() / 100.0 } Thread.sleep(100) } } } ``` -------------------------------- ### Toggle Fullscreen in Modal Window Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Layout_Debugger.html Use a button's action handler to toggle the fullscreen state of a modal window. This example assumes 'modalStage' is accessible. ```kotlin button("Toggle fullscreen") { setOnAction { with (modalStage) { isFullScreen = !isFullScreen } } } ``` -------------------------------- ### Complete Counter View with FXML Binding Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/10_FXML.html This complete View demonstrates loading FXML, defining a counter property, injecting the label using `fxid`, and binding the counter to the label's text. The `init` block sets up the binding. ```kotlin class CounterView : View() { override val root : BorderPane by fxml() val counter = SimpleIntegerProperty() val counterLabel: Label by fxid() init { counterLabel.bind(counter) } fun increment() { counter.value += 1 } } ``` -------------------------------- ### Add Customer Button Action with onComplete Callback Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Wizard.html Trigger a CustomerWizard, define an onComplete callback to handle database insertion and opening a CustomerEditor, and then open the wizard modal. ```kotlin button("Add Customer").action { find { onComplete { runAsync { database.insert(customer.item) } ui { workspace.dockInNewScope(customer.item) } } openModal() } } ``` -------------------------------- ### Basic VBox Layout Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/7_Layouts_and_Menus.html Stacks controls vertically in the order they are declared. Use this for simple vertical arrangements. ```kotlin vbox { button("Button 1").setOnAction { println("Button 1 Pressed") } button("Button 2").setOnAction { println("Button 2 Pressed") } } ``` -------------------------------- ### Create a Quadratic Bézier Curve with TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/9_Shapes_and_Animation.html Draws a quadratic Bézier curve using start, end, and a single control point, with a specified fill color. ```kotlin quadcurve { startX = 0.0 startY = 150.0 endX = 150.0 endY = 150.0 controlX = 75.0 controlY = 0.0 fill = Color.BURLYWOOD } ``` -------------------------------- ### Custom Workspace with Drawer Navigation Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Workspaces.html Configure a Workspace with a default docked view and static items in the left drawer for navigation. ```kotlin // A Form based View we will dock in the workspace editor area class CustomerEditor : View("Customer Editor") { override val root = form { fieldset(title) { field("Name") { textfield() } field("Username") { textfield() } button("Save") } } } class DrawerWorkspace : Workspace() { init { // Dock the Customer Editor by default dock() } init { // Add items to the left drawers with(leftDrawer) { item("Screencasts") { webview { prefWidth = 470.0 engine.userAgent = iPhoneUserAgent engine.load(TornadoFXScreencastsURI) } } item("Links") { listview(links) { cellFormat { link -> graphic = hyperlink(link.name).action { hostServices.showDocument(link.uri) } } } } item("People") { tableview(people) { column("Name", Person::name) column("Nick", Person::nick) } } } } // Sample data and configuration omitted for this example } ``` -------------------------------- ### Create a Cubic Bézier Curve with TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/9_Shapes_and_Animation.html Draws a cubic Bézier curve using start, end, and two control points, with a specified fill color. ```kotlin cubiccurve { startX = 0.0 startY = 50.0 controlX1 = 25.0 controlY1 = 0.0 controlX2 = 75.0 controlY2 = 100.0 endX = 150.0 endY = 50.0 fill = Color.GREEN } ``` -------------------------------- ### MenuBar with Actions, Graphics, and Shortcuts Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/7_Layouts_and_Menus.html Defines a menu bar with menu items that include optional keyboard shortcuts, graphics, and action lambdas to be executed upon selection. Ensure 'fbIcon' and 'twIcon' are defined graphic objects. ```kotlin menubar { menu("File") { menu("Connect") { item("Facebook", graphic = fbIcon).action { println("Connecting Facebook!") } item("Twitter", graphic = twIcon).action { println("Connecting Twitter!") } } item("Save","Shortcut+S").action { println("Saving!") } item("Quit","Shortcut+Q").action { println("Quitting!") } } menu("Edit") { item("Copy","Shortcut+C").action { println("Copying!") } item("Paste","Shortcut+V").action { println("Pasting!") } } } ``` -------------------------------- ### Configure Java 11 Module Permissions Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/2_Setting_Up.html Set up the module-info.java file to declare required modules and open packages for Java 11's module system. Replace 'yourmodulename' and 'your.package.to.ui.classes' with your project's specific details. ```java module yourmodulename { requires javafx.controls; requires javafx.graphics; requires tornadofx; requires kotlin.stdlib; opens your.package.to.ui.classes; } ``` -------------------------------- ### Register JavaFX App with TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Integration.html Register your existing JavaFX Application with the TornadoFX runtime by calling `FX.registerApplication` in your `Application` class `start()` method. This is available as of version 1.4.3. ```java public class LegacyApp extends Application { public void start(Stage primaryStage) throws Exception { // Register JavaFX app with the TornadoFX runtime FX.registerApplication(this, primaryStage); } } ``` -------------------------------- ### Basic HBox Layout Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/7_Layouts_and_Menus.html Stacks controls horizontally from left to right in the order they are declared. Ideal for horizontal arrangements. ```kotlin hbox { button("Button 1").setOnAction { println("Button 1 Pressed") } button("Button 2").setOnAction { println("Button 2 Pressed") } } ``` -------------------------------- ### Conditional Cell Formatting in TableView Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/1_Why_TornadoFX.html This example shows how to apply conditional formatting to TableView cells using the `cellFormat` extension function. It styles rows where the 'Age' is less than 18. ```kotlin tableview { items = persons column("ID", Person::idProperty) column("Name", Person::nameProperty) column("Birthday", Person::birthdayProperty) readonlyColumn("Age", Person::age).cellFormat { text = it.toString() style { if (it < 18) { backgroundColor += c("#8b0000") textFill = Color.WHITE } } } } ``` -------------------------------- ### Basic MenuBar Structure Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/7_Layouts_and_Menus.html Constructs a simple menu bar with nested menus and menu items. This provides a foundational structure for organizing application commands. ```kotlin menubar { menu("File") { menu("Connect") { item("Facebook") item("Twitter") } item("Save") item("Quit") } menu("Edit") { item("Copy") item("Paste") } } ``` -------------------------------- ### Register TornadoFX App with BundleActivator Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/OSGi.html Implement a BundleActivator to register your TornadoFX App class using context.registerApplication. This allows the application to be started and stopped dynamically within an OSGi container. ```kotlin class Activator : BundleActivator { override fun start(context: BundleContext) { context.registerApplication(MyApp::class) } override fun stop(context: BundleContext) { } } ``` -------------------------------- ### Binding TextField to ViewModel Property Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/11_Editing_Models_and_Validation.html This example shows how to bind a TextField directly to a property of a ViewModel. This simplifies UI development by automatically reflecting changes between the TextField and the ViewModel's data. ```kotlin field("Name") { textfield(model.name) } ``` -------------------------------- ### Create a DatePicker Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Implement a DatePicker to allow users to select dates from a calendar. You can set the initial value and manipulate it further. ```kotlin datepicker { value = LocalDate.now() } ``` -------------------------------- ### Add Query Parameters to Request Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/JSON_and_REST.html Appends URL-encoded query parameters to a request URI using the `queryString` extension on a Map. This example demonstrates adding an 'id' parameter to a PUT request. ```kotlin val params = mapOf("id" to 1) api.put("customers${params.queryString}", customer).one().toModel() ``` -------------------------------- ### Access TornadoFX View from JavaFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Integration.html Access a TornadoFX View's root node from plain JavaFX code. Use `FX.find` to get an instance of the View and then retrieve its root node. ```java // Create a BorderPane for our Scene BorderPane root = new BorderPane(); // Lookup a TornadoFX view and set it's root as the center node HBox fxView = FX.find(MyView.class).getRoot(); root.setCenter(fxView); ``` -------------------------------- ### Create a ProgressBar Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Visualize process completion with a ProgressBar. It accepts a Double value between 0.0 and 1.0 to indicate progress. ```kotlin progressbar(0.5) ``` -------------------------------- ### Complete CustomerWizard and Page Definitions Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Wizard.html Provides the full implementation of `CustomerWizard`, `BasicData`, and `AddressInput` views, integrating the improved validation and button logic. ```kotlin class CustomerWizard : Wizard() { val customer: CustomerModel by inject() override val canGoNext = currentPageComplete override val canFinish = allPagesComplete init { add(BasicData::class) add(AddressInput::class) } } class BasicData : View("Basic Data") { val customer: CustomerModel by inject() override val complete = customer.valid(customer.name) override val root = form { fieldset(title) { field("Type") { combobox(customer.type, Customer.Type.values().toList()) } field("Name") { textfield(customer.name).required() } } } } class AddressInput : View("Address") { val customer: CustomerModel by inject() override val complete = customer.valid(customer.zip, customer.city) override val root = form { fieldset(title) { field("Zip/City") { textfield(customer.zip) { prefColumnCount = 5 required() } textfield(customer.city).required() } } } } ``` -------------------------------- ### Load Resource as AudioClip URL Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Load a resource file as an `AudioClip` by converting its URL to an external form. This is the traditional JavaFX approach. ```kotlin val myAudioClip = AudioClip(MyView::class.java.getResource("mysound.wav").toExternalForm()) ``` -------------------------------- ### Unsubscribe Event After N Times Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/EventBus.html Control how many times an event listener should be triggered before it is automatically unsubscribed by passing the `times` parameter to the `subscribe` function. This example limits the alert to appear only twice. ```kotlin object MyEvent : FXEvent() class MyView : View() { override val root = stackpane { paddingAll = 100 button("Fire!").action { fire(MyEvent) } } init { subscribe(times = 2) { alert(INFORMATION, "Event received!", "This message should only appear twice.") } } } ``` -------------------------------- ### Configure REST Client Base URI Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/JSON_and_REST.html Shows how to configure a base URI for the TornadoFX REST client within the `init` block of your `App` class. This is useful when making multiple calls to the same API. ```kotlin class MyApp : App() { val api: Rest by inject() init { api.baseURI = "https://contoso.com/api" } } ``` -------------------------------- ### Create ScatterChart Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/8_Charts.html A ScatterChart plots data points without lines or bars, useful for identifying clusters in large datasets. This example plots machine capacities by week for two product lines. ```kotlin scatterchart("Machine Capacity by Product/Week", NumberAxis(), NumberAxis()) { series("Product X") { data(1,24) data(2,22) data(3,23) data(4,19) data(5,18) } series("Product Y") { data(1,12) data(2,15) data(3,9) data(4,11) data(5,7) } } ``` -------------------------------- ### Create TreeView with Functional Builder Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/5_Data_Controls.html Demonstrates creating a TreeView using the 'treeview()' builder. It populates departments and their associated persons. ```kotlin val departments = persons .map { it.department } .distinct().map { Person(it, "") } treeview { // Create root item root = TreeItem(Person("Departments", "")) // Make sure the text in each TreeItem is the name of the Person cellFormat { text = it.name } // Generate items. Children of the root item will contain departments populate { if (parent == root) departments else persons.filter { it.department == parent.value.name } } } ``` -------------------------------- ### Get a BooleanBinding for a Specific Property's Dirty State Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/11_Editing_Models_and_Validation.html Obtain a `BooleanBinding` that dynamically reflects the dirty state of a specific property within the ViewModel. This is useful for reacting to changes in individual fields. ```kotlin val nameDirtyProperty = model.dirtyStateFor(PersonModel::name) ``` -------------------------------- ### Custom Validator with Textfield Manipulation Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/11_Editing_Models_and_Validation.html Adds a custom validator within nested curly braces for a `textfield`, allowing for further manipulation of the text field itself. This example shows how to attach a validator that checks for blank input. ```kotlin field("Name") { textfield(model.name) { validator { if (it.isNullOrBlank()) error("The name field is required") else null } } } ``` -------------------------------- ### Nesting Controls with Builders Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Demonstrates nesting `hbox` and `textfield` controls within a `vbox` using TornadoFX builder functions for structured UI layout. ```kotlin import tornadofx.* class MyView : View() { override val root = vbox { hbox { label("First Name") textfield() } hbox { label("Last Name") textfield() } button("LOGIN") { useMaxWidth = true } } } ``` -------------------------------- ### Inject ViewModel into PersonList View Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/11_Editing_Models_and_Validation.html This example demonstrates injecting a `PersonModel` into a `PersonList` view, which displays a table of persons and binds the selected item to the model. This allows the table view to interact with the model for editing. ```kotlin class PersonList : View("Person List") { val persons = listOf(Person("John", "Manager"), Person("Jay", "Worker bee")).observable() val model : PersonModel by inject() override val root = tableview(persons) { title = "Person" column("Name", Person::nameProperty) column("Title", Person::titleProperty) bindSelected(model) } } ``` -------------------------------- ### Create a Hyperlink Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Implement a Hyperlink control that can trigger an action when clicked. This mimics the behavior of web hyperlinks. ```kotlin hyperlink("Open File").action { println("Opening file...") } ``` -------------------------------- ### TableView with Cell Editing and Dirty Tracking Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/11_Editing_Models_and_Validation.html Enable direct cell editing and dirty state tracking in a TableView. This setup allows for easy cell navigation, editing, and visual indication of modified cells. ```kotlin import tornadofx.* class MyApp: App(MyView::class) class MyView : View("My View") { val controller: CustomerController by inject() var tableViewEditModel: TableViewEditModel by singleAssign() override val root = borderpane { top = buttonbar { button("COMMIT").setOnAction { tableViewEditModel.commit() } button("ROLLBACK").setOnAction { tableViewEditModel.rollback() } } center = tableview { items = controller.customers isEditable = true column("ID",Customer::idProperty) column("FIRST NAME", Customer::firstNameProperty).makeEditable() column("LAST NAME", Customer::lastNameProperty).makeEditable() enableCellEditing() //enables easier cell navigation/editing enableDirtyTracking() //flags cells that are dirty tableViewEditModel = editModel } } } class CustomerController : Controller() { val customers = listOf( Customer(1, "Marley", "John"), Customer(2, "Schmidt", "Ally"), Customer(3, "Johnson", "Eric") ).observable() } class Customer(id: Int, lastName: String, firstName: String) { val lastNameProperty = SimpleStringProperty(this, "lastName", lastName) var lastName by lastNameProperty val firstNameProperty = SimpleStringProperty(this, "firstName", firstName) var firstName by firstNameProperty val idProperty = SimpleIntegerProperty(this, "id", id) var id by idProperty } ``` -------------------------------- ### Basic TabPane with VBox and HBox Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/7_Layouts_and_Menus.html Defines a TabPane with two tabs, each containing different UI elements arranged in VBox and HBox containers. ```kotlin tabpane { tab("Screen 1") { vbox { button("Button 1") button("Button 2") } } tab("Screen 2") { hbox { button("Button 3") button("Button 4") } } } ``` -------------------------------- ### Define a Reusable Fragment in TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Create a `Fragment` to define a piece of UI that can be instantiated multiple times, unlike a `View` which is typically a singleton. This example shows a simple `Fragment` opened as a modal dialog from a `View`. ```kotlin import javafx.stage.StageStyle import tornadofx.* class MyView : View() { override val root = vbox { button("Press Me") { action { find().openModal(stageStyle = StageStyle.UTILITY) } } } } class MyFragment: Fragment() { override val root = label("This is a popup") } ``` -------------------------------- ### Create and Dock View in New Scope Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Workspaces.html Manually create a new scope, find a view within it, and dock it to the workspace. This ensures the view operates in an isolated scope. ```kotlin val newScope = Scope(workspace) val customerList = find(newScope) workspace.dock(customerList) ``` -------------------------------- ### Apply Contextual Styles with Modifier Selections in TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/6_CSS.html Use modifier selections with `and()` to apply styles based on element states like hover or selection. This example styles buttons on hover and selected cells in a list view. ```kotlin import javafx.scene.paint.Color import tornadofx.Stylesheet class Styles : Stylesheet() { init { button { and(hover) { backgroundColor += Color.RED } } cell { and(selected) { backgroundColor += Color.RED } } } } ``` ```kotlin import tornadofx.* class MyApp: App(MyView::class, Styles::class) class MyView : View("My View") { val listItems = listOf("Alpha","Beta","Gamma").observable() and override val root = vbox { button("Hover over me") listview(listItems) } } ``` -------------------------------- ### Load JSON and Stream Resources Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Utilize the `resources` helper to load JSON files as objects or arrays, or retrieve files as input streams. ```kotlin val myJsonObject = resources.json("myobject.json") val myJsonArray = resources.jsonArray("myarray.json") val myStream = resources.stream("somefile") ``` -------------------------------- ### English Resource Bundle Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/10_FXML.html Define English text for UI elements using a .properties file named after your View. ```properties clickToIncrement=Click to increment ``` -------------------------------- ### Define and Apply CSS Mixins in TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/6_CSS.html Use mixins to define reusable sets of CSS properties. Apply them to classes or elements to avoid repeating styles. This example defines a `redAllTheThings` mixin and applies it to a custom class and specific controls. ```kotlin import javafx.scene.paint.Color import javafx.scene.text.FontWeight import tornadofx.* class Styles : Stylesheet() { companion object { val redStyle by cssclass(). } init { val redAllTheThings = mixin { backgroundInsets += box(5.px) borderColor += box(Color.RED) textFill = Color.RED } redStyle { +redAllTheThings } s(textInput, label) { +redAllTheThings fontWeight = FontWeight.BOLD } passwordField { +redAllTheThings backgroundColor += Color.YELLOW } } } ``` ```kotlin class MyApp: App(MyView::class, Styles::class) class MyView : View("My View") { override val root = vbox { label("Enter your login") form { fieldset{ field("Username") { textfield() } field("Password") { passwordfield() } } } button("Go!") { addClass(Styles.redStyle) } } } ``` -------------------------------- ### JPro Application Entry Point Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Scopes.html Subclass `JProApplication` to define the entry point for a JPro-based TornadoFX application. It manages the lifecycle and sets up the custom `JProScope` for the TornadoFX app. ```kotlin class Main : JProApplication() { val app = OurTornadoFXApp() override fun start(primaryStage: Stage) { app.scope = JProScope(primaryStage) app.start(primaryStage) } override fun stop() { app.stop() super.stop() } } ``` -------------------------------- ### Create a ListView with an ObservableList Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/5_Data_Controls.html Initialize a ListView with an `ObservableList` for automatic updates. The type can be inferred from the list. ```kotlin val greekLetters = listOf("Alpha","Beta", "Gamma","Delta","Epsilon").asObservable() listview(greekLetters) { selectionModel.selectionMode = SelectionMode.MULTIPLE } ``` -------------------------------- ### Define Shortcut with String Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html A more concise way to define shortcuts using a string representation of the key combination. Ensure the `doSomething()` function is defined. ```kotlin shortcut("Ctrl+Y") { doSomething() } ``` -------------------------------- ### Create a TextArea Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Use TextArea for multiline text input. You can set initial text and manipulate its content upon declaration. ```kotlin textarea("Type memo here") { selectAll() } ``` -------------------------------- ### Basic Node Animation with Timeline Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/9_Shapes_and_Animation.html Animate a node's property by creating a Timeline with a KeyFrame that specifies a KeyValue for the property change over a set duration. ```kotlin val rectangle = rectangle(width = 60.0,height = 40.0) { padding = Insets(20.0) } timeline { keyframe(Duration.seconds(5.0)) { keyvalue(rectangle.rotateProperty(),90.0) } } ``` -------------------------------- ### Inject Service with `di` Delegate (Guice) Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Dependency_Injection.html Use the `di` delegate to inject beans from an external DI framework like Guice. This delegate accepts any bean type. ```kotlin val MyView : View() { val helloService: HelloService by di() } ``` -------------------------------- ### Injecting Views with find() and inject() Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Demonstrates explicit retrieval of `TopView` using `find()` and lazy injection of `BottomView` using `inject()` delegate to assign their root elements. ```kotlin import javafx.scene.control.Label import javafx.scene.layout.BorderPane import tornadofx.* class MasterView : View() { // Explicitly retrieve TopView val topView = find(TopView::class) // Create a lazy reference to BottomView val bottomView: BottomView by inject() override val root = borderpane { top = topView.root bottom = bottomView.root } } ``` -------------------------------- ### Create a ListView with String Items Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/5_Data_Controls.html Use the `listview` builder to create a ListView and add String items. Multiple selections can be enabled using `selectionModel.selectionMode`. ```kotlin listview { items.add("Alpha") items.add("Beta") items.add("Gamma") items.add("Delta") items.add("Epsilon") selectionModel.selectionMode = SelectionMode.MULTIPLE } ``` -------------------------------- ### Eagerly Load Controller for Events Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/EventBus.html Eagerly load a controller in the `init` block of your `App` subclass to ensure its event subscriptions are registered immediately, especially if the controller has no other references. ```kotlin class MyApp : App(MainView::class) { init { // Eagerly load CustomerController so it can receive events find(CustomerController::class) } } ``` -------------------------------- ### Define a Basic View Structure in TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/9_Shapes_and_Animation.html Sets up a basic TornadoFX view with a StackPane containing a Group, which is a common pattern for adding shapes. ```kotlin class MyView: View() { override val root = stackpane { group { //shapes will go here } } } ``` -------------------------------- ### View with Controller for Input Handling Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html Use this pattern to separate UI logic from data handling. Inject a Controller to manage actions triggered by UI elements like buttons. ```kotlin import tornadofx.* class MyView : View() { val controller: MyController by inject() val input = SimpleStringProperty() override val root = form { fieldset { field("Input") { textfield(input) } button("Commit") { action { controller.writeToDb(input.value) input.value = "" } } } } } class MyController: Controller() { fun writeToDb(inputValue: String) { println("Writing $inputValue to database!") } } ``` -------------------------------- ### Chaining `apply` with `with` for Button Styling Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Demonstrates chaining the `apply` function within a `with` block to configure properties like `textFill` and `action` on a Button. ```kotlin import javafx.scene.control.Button import javafx.scene.layout.VBox import javafx.scene.paint.Color import tornadofx.* class MyView : View() { override val root = VBox() init { with(root) { this += Button("Press Me").apply { textFill = Color.RED action { println("Button pressed!") } } } } } ``` -------------------------------- ### Dock View in New Scope (Shorthand) Source: https://edvin.gitbooks.io/tornadofx-guide/content/part2/Workspaces.html A concise way to create a new scope, find a view within it, and dock it to the workspace in a single call. Use when a view needs its own isolated scope. ```kotlin workspace.dockInNewScope() ``` -------------------------------- ### Create a Rectangle with TornadoFX Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/9_Shapes_and_Animation.html Demonstrates multiple ways to create a rectangle node in TornadoFX. Default values are used if parameters are omitted. ```kotlin rectangle { width = 100.0 height = 100.0 } ``` ```kotlin rectangle(width = 100.0, height = 100.0) ``` ```kotlin rectangle(0.0, 0.0, 100.0, 100.0) ``` -------------------------------- ### Create a ComboBox with Observable List Items Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Use the `combobox()` builder to create a ComboBox and populate it with items from an `FXCollections.observableArrayList`. ```kotlin val texasCities = FXCollections.observableArrayList("Austin", "Dallas","Midland", "San Antonio","Fort Worth") combobox { items = texasCities } ``` -------------------------------- ### Create an ObservableList of Persons Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/5_Data_Controls.html Prepare a list of `Person` objects as an `ObservableList` to be used with a `TableView`. ```kotlin private val persons = listOf( 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)) ).asObservable() ``` -------------------------------- ### Saving Control References with `singleAssign` Source: https://edvin.gitbooks.io/tornadofx-guide/content/part1/4_Basic_Controls.html Shows how to save references to controls like TextFields using `singleAssign()` delegates, ensuring properties are assigned only once. ```kotlin import javafx.scene.control.TextField import tornadofx.* class MyView : View() { override val root = VBox() init { with(root) { val firstNameField: TextField by singleAssign() firstNameField = textfield() } } } ```