{"id":20239168,"url":"https://github.com/edvin/tornadofx-controls","last_synced_at":"2025-07-17T23:07:15.344Z","repository":{"id":57738190,"uuid":"49786238","full_name":"edvin/tornadofx-controls","owner":"edvin","description":"CSS Stylable Controls for JavaFX","archived":false,"fork":false,"pushed_at":"2020-10-12T18:46:59.000Z","size":464,"stargazers_count":109,"open_issues_count":5,"forks_count":16,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-07-15T04:59:39.443Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edvin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-16T18:48:19.000Z","updated_at":"2025-04-13T14:47:36.000Z","dependencies_parsed_at":"2022-08-24T11:40:14.926Z","dependency_job_id":null,"html_url":"https://github.com/edvin/tornadofx-controls","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/edvin/tornadofx-controls","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edvin%2Ftornadofx-controls","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edvin%2Ftornadofx-controls/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edvin%2Ftornadofx-controls/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edvin%2Ftornadofx-controls/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edvin","download_url":"https://codeload.github.com/edvin/tornadofx-controls/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edvin%2Ftornadofx-controls/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265677366,"owners_count":23809952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T08:37:47.928Z","updated_at":"2025-07-17T23:07:15.035Z","avatar_url":"https://github.com/edvin.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tornado FXControls\n\nCSS Stylable Controls for JavaFX\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/no.tornado/tornadofx-controls/badge.svg)](https://search.maven.org/#search|ga|1|no.tornado.tornadofx-controls)\n\n## DatePickerTableCell\n\nTableCell that supports editing of `LocalDate` properties with a DatePicker.\n \n## DateTimePicker\n\nAn extension to the JavaFX DatePicker control that lets you input the the time and date in with a configurable format\nand operate on a `LocalDateTime` value.\n\n## ListMenu\n\nA menu that behaves and looks like a typical `ul`/`li` based *HTML5* menu.\n\n![ListMenuDemo](/screenshots/listmenu.gif?raw=true \"ListMenuDemo\")\n\n - Configurable `orientation` and `iconPosition`.\n - Track user selection with `active` observable property\n - Pseudo state `active` for CSS styling\n - Custom css property `-fx-graphic-fixed-size` to align icons of different sizes, which are often the case for font based icons.\n - FXML compatible\n - [ListMenuDemo](       https://github.com/edvin/tornadofx-controls/blob/master/src/test/java/tornadofx/control/test/ListMenuDemo.java) source code\n - [Custom CSS Example] (https://github.com/edvin/tornadofx-controls/blob/master/src/test/resources/custom.css)\n\n### NaviSelect\n\nA chooser with a navigate-to button that lets you select an entry and also edit it. The select mechanism must be implemented manually,\nfor example by opening a dialog with a search field and a list view.\n\n![](http://i.imgur.com/IvfGVuw.png)\n\nTypical use case can be selecting a customer, but the complete customer list cannot be loaded into the dropdown, so you need to\nopen a dialog to choose. The navigate-to button would take you to a customer edit screen.\n\n```java\nCustomer customer = customerService.getCustomer(42);\nNaviSelect\u003cCustomer\u003e navi = new NaviSelect\u003c\u003e();\nnavi.setValue(customer);\nnavi.setOnEdit(event -\u003e {\n    // Show dialog to search for customers, when done, set the new value into the navi\n    navi.setValue(newlySelectedCustomer);\n});\n```\n\nTo override how the customer is rendered in the dropdown you can configure the visual converter:\n\n```java\nnavi.setVisualConverter(Customer::getName);\n```\n\n### Create programatically\n\n```java\nListMenu menu = new ListMenu(\n\tnew ListItem(\"Contacts\", icon(FontAwesomeIcon.USER)),\n\tnew ListItem(\"Projects\", icon(FontAwesomeIcon.SUITCASE)),\n\tnew ListItem(\"Settings\", icon(FontAwesomeIcon.COG))\n);\n\n// Listen for selection\nmenu.activeProperty().addListener((observable, oldValue, newValue) -\u003e {\n\t// Navigate based on ListItem 'newValue'\n});\n```\n\n### Create with FXML\n\n```xml\n\u003cListMenu orientation=\"VERTICAL\" iconPosition=\"LEFT\"\u003e\n\t\u003cListItem active=\"true\" text=\"Contacts\"\u003e\n\t\t\u003cgraphic\u003e\n\t\t\t\u003cFontAwesomeIconView glyphName=\"USER\"/\u003e\n\t\t\u003c/graphic\u003e\n\t\u003c/ListItem\u003e\n\t\u003cListItem text=\"Projects\"\u003e\n\t\t\u003cgraphic\u003e\n\t\t\t\u003cFontAwesomeIconView glyphName=\"SUITCASE\"/\u003e\n\t\t\u003c/graphic\u003e\n\t\u003c/ListItem\u003e\n\t\u003cListItem text=\"Settings\"\u003e\n\t\t\u003cgraphic\u003e\n\t\t\t\u003cFontAwesomeIconView glyphName=\"COG\"/\u003e\n\t\t\u003c/graphic\u003e\n\t\u003c/ListItem\u003e\n\u003c/ListMenu\u003e\n```\n## Form layout\n\n![Form](/screenshots/form.png?raw=true \"Form\")\n\nA CSS stylable Form layout that is very convenient to use both with FXML and in code.\n \n### FXML Example\n \n```xml\n\u003cForm\u003e\n    \u003cFieldset text=\"Contact Information\" inputGrow=\"SOMETIMES\"\u003e\n        \u003cField text=\"Id\"\u003e\n            \u003cTextField /\u003e\n        \u003c/Field\u003e\n        \u003cField text=\"Username\"\u003e\n            \u003cTextField /\u003e\n        \u003c/Field\u003e\n        \u003cField text=\"Zip/City\"\u003e\n            \u003cTextField minWidth=\"80\" maxWidth=\"80\" /\u003e\n            \u003cTextField /\u003e\n        \u003c/Field\u003e\n        \u003cField\u003e\n            \u003cButton text=\"Save\"/\u003e\n        \u003c/Field\u003e\n    \u003c/Fieldset\u003e\n\u003c/Form\u003e \n```\n \n### Java Example\n \n```java\nForm form = new Form();\n\nFieldset contactInfo = form.fieldset(\"Contact Information\");\n\ncontactInfo.field(\"Id\", new TextField());\ncontactInfo.field(\"Username\", new TextField());\n\nTextField zipInput = new TextField();\nzipInput.setMinWidth(80);\nzipInput.setMaxWidth(80);\ncontactInfo.field(\"Zip/City\", zipInput, new TextField());\n\ncontactInfo.field(new Button(\"Save\"));\n```\n\n### Responsive layout\n\nA fieldset can lay out it's labels on the same line as the inputs (`orientation=HORIZONTAL`)\nor the labels can be laid out above the inputs (`orientation=VERTICAL`).\n\nBy changing the `wrapWidth` property on a fieldset you can make a fieldset switch from `HORIZONTAL`\n to `VERTICAL` automatically when the form is resized to a smaller width than `wrapWidth`.\n \n### Legends\n\nA fieldset can have an optional icon specified for it's legend by setting the `icon` property\nto any node.\n\n### CSS\n\nUse the default [CSS Stylesheet](https://github.com/edvin/tornadofx-controls/blob/master/src/main/resources/tornadofx/control/form.css)\nas a starting point. The substructure of a `Form` is described below.\n\n#### Substructure\n\n\n- form - VBox\n\t- fieldset - VBox\n\t\t- legend - Label\n\t\t- field - Field\n\t\t\t- label-container - HBox\n\t\t\t\t- label - Label\n\t\t\t- input-container - HBox\n\t\t\t\t- arbitrary input components\n\n## UnitConverter for TextField (kMGTPE)\n\nBind a `Long` property to a TextField with `UnitConverter` and you can write *2G* instead of 2147483648.\n\n```java\nTextField storageInput = new TextField()\nstorageInput.textProperty().bindBidirectional(product.sizeProperty(), new UnitConverter())\n```\n\nOptionally configure `binary (true/false)` and `separator` (default \"\").\n\n## DirtyState Tracker\n\nTrack dirty states for a collection of properties, with undo feature to rollback changes.\n\n```java\n// Track all properties in customer\nDirtyState dirtyState = new DirtyState(customer);\n\n// Track only username and password\nDirtyStateTracker dirtyState = new DirtyStateTracker(customer,\n\tcustomer.usernameProperty(), customer.passwordProperty());\n\n// Disable save button until anything is changed\nsaveButton.disableProperty().bind(dirtyState.not())\n\n// Undo changes\nundoButton.setOnAction(event -\u003e dirtyState.undo());\n\n// Show undo button when changes are performed\nundoButton.visibleProperty().bind(dirtyState);\n```\n\nSee the JavaDoc for more information and options. \n\n## LeanPropertyValueFactory\n\nFancy having public fields for your JavaFX properties instead of public methods in your model objects?\nThis PropertyValueFactory allows you to use these fields with a TableView:\n\n```java\npublic class Customer {\n\tpublic field idProperty = SimpleObjectProperty\u003cInteger\u003e();\n\tpublic field nameProperty = SimpleObjectProperty\u003cString\u003e();\n\t// Getters and setters if you want :)\n}\n```\n\n```xml\n\u003cTableView\u003e\n\t\u003ccolumns\u003e\n\t\t\u003cTableColumn text=\"Id\"\u003e\n\t\t\t\u003ccellValueFactory\u003e\n\t\t\t\t\u003cLeanPropertyValueFactory property=\"id\"/\u003e\n\t\t\t\u003c/cellValueFactory\u003e\n\t\t\u003c/TableColumn\u003e\n\t\t\u003cTableColumn text=\"Name\"\u003e\n\t\t\t\u003ccellValueFactory\u003e\n\t\t\t\t\u003cLeanPropertyValueFactory property=\"name\"/\u003e\n\t\t\t\u003c/cellValueFactory\u003e\n\t\t\u003c/TableColumn\u003e\n\t\u003c/columns\u003e\n\u003c/TableView\u003e\n\n```\n\n\n## Installation\n\n### Maven\n```xml\n\u003cdependency\u003e\n\t\u003cgroupId\u003eno.tornado\u003c/groupId\u003e\n\t\u003cartifactId\u003etornadofx-controls\u003c/artifactId\u003e\n\t\u003cversion\u003e1.0.4\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n\n```groovy\ncompile 'no.tornado:tornadofx-controls:1.0.4'\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedvin%2Ftornadofx-controls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedvin%2Ftornadofx-controls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedvin%2Ftornadofx-controls/lists"}