{"id":26206620,"url":"https://github.com/dlemmermann/FormsFX","last_synced_at":"2025-03-12T05:01:55.444Z","repository":{"id":25142227,"uuid":"103286363","full_name":"dlsc-software-consulting-gmbh/FormsFX","owner":"dlsc-software-consulting-gmbh","description":"A framework for easily creating forms for a JavaFX UI.","archived":false,"fork":false,"pushed_at":"2023-09-05T11:11:21.000Z","size":4007,"stargazers_count":642,"open_issues_count":22,"forks_count":94,"subscribers_count":33,"default_branch":"master-11","last_synced_at":"2024-10-30T06:01:05.870Z","etag":null,"topics":["desktop","forms","javafx","ui","ui-components"],"latest_commit_sha":null,"homepage":"","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/dlsc-software-consulting-gmbh.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-09-12T15:11:31.000Z","updated_at":"2024-10-24T15:37:12.000Z","dependencies_parsed_at":"2024-01-13T07:25:57.230Z","dependency_job_id":"beffe79a-7fa8-4715-865b-859278d4f369","html_url":"https://github.com/dlsc-software-consulting-gmbh/FormsFX","commit_stats":null,"previous_names":["dlemmermann/formsfx"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlsc-software-consulting-gmbh%2FFormsFX","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlsc-software-consulting-gmbh%2FFormsFX/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlsc-software-consulting-gmbh%2FFormsFX/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlsc-software-consulting-gmbh%2FFormsFX/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dlsc-software-consulting-gmbh","download_url":"https://codeload.github.com/dlsc-software-consulting-gmbh/FormsFX/tar.gz/refs/heads/master-11","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243158972,"owners_count":20245672,"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":["desktop","forms","javafx","ui","ui-components"],"created_at":"2025-03-12T05:01:17.564Z","updated_at":"2025-03-12T05:01:55.434Z","avatar_url":"https://github.com/dlsc-software-consulting-gmbh.png","language":"Java","funding_links":[],"categories":["Community","Libraries, Tools and Projects"],"sub_categories":["Libraries"],"readme":"[![JFXCentral](https://img.shields.io/badge/Find_me_on-JFXCentral-blue?logo=googlechrome\u0026logoColor=white)](https://www.jfx-central.com/libraries/formsfx)\n\n[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=dlsc-software-consulting-gmbh_FormsFX\u0026metric=bugs)](https://sonarcloud.io/dashboard?id=dlsc-software-consulting-gmbh_afterburner.fx)\n[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=dlsc-software-consulting-gmbh_FormsFX\u0026metric=code_smells)](https://sonarcloud.io/dashboard?id=dlsc-software-consulting-gmbh_afterburner.fx)\n[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=dlsc-software-consulting-gmbh_FormsFX\u0026metric=ncloc)](https://sonarcloud.io/dashboard?id=dlsc-software-consulting-gmbh_afterburner.fx)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=dlsc-software-consulting-gmbh_FormsFX\u0026metric=sqale_rating)](https://sonarcloud.io/dashboard?id=dlsc-software-consulting-gmbh_afterburner.fx)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=dlsc-software-consulting-gmbh_FormsFX\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=dlsc-software-consulting-gmbh_afterburner.fx)\n[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=dlsc-software-consulting-gmbh_FormsFX\u0026metric=reliability_rating)](https://sonarcloud.io/dashboard?id=dlsc-software-consulting-gmbh_afterburner.fx)\n[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=dlsc-software-consulting-gmbh_FormsFX\u0026metric=security_rating)](https://sonarcloud.io/dashboard?id=dlsc-software-consulting-gmbh_afterburner.fx)\n[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=dlsc-software-consulting-gmbh_FormsFX\u0026metric=sqale_index)](https://sonarcloud.io/dashboard?id=dlsc-software-consulting-gmbh_afterburner.fx)\n[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=dlsc-software-consulting-gmbh_FormsFX\u0026metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=dlsc-software-consulting-gmbh_afterburner.fx)\n\n# FormsFX\n**Forms for business application made easy. Creating forms in Java has never been this easy!**\n\n[ ![Download](https://api.bintray.com/packages/dlsc-oss/repository/FormsFX/images/download.svg) ](https://bintray.com/dlsc-oss/repository/FormsFX/_latestVersion)\n[![Build Status](https://travis-ci.org/dlemmermann/formsfx.svg?branch=master)](https://travis-ci.org/dlemmermann/formsfx)\n\n## Maven\n\nTo use this framework as part of your Maven build simply add the following dependency to your pom.xml file.\n\n```XML\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.dlsc.formsfx\u003c/groupId\u003e\n  \u003cartifactId\u003eformsfx-core\u003c/artifactId\u003e\n  \u003cversion\u003e11.3.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## What is FormsFX?\n\nCreating forms in JavaFX is a tedious and very error-prone task. FormsFX is a framework which solves this problem. It enables the developer to create forms with ease and creates well-designed and user-friendly forms by default. FormsFX offers a fluent API that is very easy to understand and reduces the amount of coding needed. It creates all the necessary bindings for the properties and *it just works*.\n\n## Main Features\n\n- Simple and understandable Fluent API\n- Different semantic items\n- Pre-defined controls\n- Validation\n- Localisation\n\n```Java\nForm loginForm = Form.of(\n        Group.of(\n                Field.ofStringType(model.usernameProperty())\n                        .label(\"Username\"),\n                Field.ofStringType(model.passwordProperty())\n                        .label(\"Password\")\n                        .required(\"This field can’t be empty\")\n        )\n).title(\"Login\");\n```\n\n## Semantics\n\nFormsFX offers different semantic layers. The largest entity is the form. It contains groups and sections, which in turn act as containers for fields. Fields are the end user's primary point of interaction as they handle data input and presentation.\n\n## Defining a form\n\nCreating a form is as simple as calling `Form.of()`.\n\n```Java\nForm.of(\n        Group.of(\n                Field.ofStringType(\"\")\n                        .label(\"Username\"),\n                Field.ofStringType(\"\")\n                        .label(\"Password\")\n                        .required(\"This field can’t be empty\")\n        ),\n        Group.of(…)\n).title(\"Login\");\n```\n\nFields have a range of options that define their semantics and change their functionality.\n\nOption | Description\n------ | -----------\n`label(String)` | Describes the field’s content in a concise manner. This description is always visible and usually placed next to the editable control.\n`tooltip(String)` | This contextual hint further describes the field. It is usually displayed on hover or focus.\n`placeholder(String)` | This hint describes the expected input as long as the field is empty.\n`required(boolean)` \u003cbr /\u003e `required(String)` | Determines, whether entry in this field is required for the correctness of the form.\n`editable(boolean)` | Determines, whether end users can edit the contents of this field.\n`id(String)` | Describes the field with a unique ID. This is not visible directly, but can be used for styling purposes.\n`styleClass(List\u0026lt;String\u0026gt;)` | Adds styling hooks to the field. This can be used on the view layer.\n`span(int)` \u003cbr /\u003e `span(ColSpan)` | Determines, how many columns the field should span on the view layer. Can be a number between 1 and 12 or a ColSpan fraction.\n`render(SimpleControl)` | Determines the control that is used to render this field on the view layer.\n\n\nThe following table shows how to create different fields and how they look by default:\n\nString Control\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003eString Control\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"./docs/images/StringField.png\" /\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\n        \u003cpre lang=\"java\"\u003eField.ofStringType(\"CHF\")\n     .label(\"Currency\")\u003c/pre\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003eInteger Control\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"./docs/images/IntegerField.png\" /\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\n        \u003cpre lang=\"java\"\u003eField.ofIntegerType(8401120)\n     .label(\"Population\")\u003c/pre\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003eDouble Control\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"./docs/images/DoubleField.png\" /\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\n        \u003cpre lang=\"java\"\u003eField.ofDoubleType(41285.0)\n       .label(\"Area\")\u003c/pre\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003eBoolean Control\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"./docs/images/BooleanField.png\" /\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\n        \u003cpre lang=\"java\"\u003eField.ofBooleanType(false)\n     .label(\"Independent\")\u003c/pre\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003eComboBox Control\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"./docs/images/ComboBoxField.png\" /\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\n        \u003cpre lang=\"java\"\u003eField.ofSingleSelectionType(Arrays.asList(\"Zürich (ZH)\", \"Bern (BE)\", …), 1)\n     .label(\"Capital\")\u003c/pre\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003eRadioButton Control\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"./docs/images/RadioButtonField.png\" /\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\n        \u003cpre lang=\"java\"\u003eField.ofSingleSelectionType(Arrays.asList(\"Right\", \"Left\"), 0)\n     .label(\"Driving on the\")\n     .render(new SimpleRadioButtonControl\u003c\u003e())\u003c/pre\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003eCheckBox Control\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"./docs/images/CheckBoxField.png\" /\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\n        \u003cpre lang=\"java\"\u003eField.ofMultiSelectionType(Arrays.asList(\"Africa\", \"Asia\", …), Collections.singletonList(2))\n     .label(\"Continent\")\n     .render(new SimpleCheckBoxControl\u003c\u003e())\u003c/pre\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003eListView Control\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003cimg src=\"./docs/images/ListField.png\" /\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\n        \u003cpre lang=\"java\"\u003eField.ofMultiSelectionType(Arrays.asList(\"Zürich (ZH)\", \"Bern (BE)\", …), Arrays.asList(0, 1, …))\n     .label(\"Biggest Cities\")\u003c/pre\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n## Rendering a form\n\nThe only point of interaction is the `FormRenderer`. It delegates rendering of further components to other renderers.\n\n```java\nPane root = new Pane();\nroot.getChildren().add(new FormRenderer(form));\n```\n\nAll fields have a default control that is used for rendering. This can be changed to another compatible implementation using the `render()` method.\n\n```java\nField.ofMultiSelectionType(…)\n        .render(new SimpleCheckBoxControl\u003c\u003e())\n```\n\n## Model\n\nForms are used to create and manipulate data. In order to use this data in other parts of an application, model classes can be used. These classes contain properties, which are then bound to the persisted value of a field.\n\n```java\nStringProperty name = new SimpleStringProperty(\"Hans\");\nField.ofStringType(name);\n```\n\nThe `persist()` and `reset()` methods can be used to store and revert field values, which in turn updates the binding.\n\nFields in FormsFX store their values in multiple steps. For free-form fields, like `StringField` or `DoubleField`, the exact user input is stored, along with a type-transformed value and a persistent value. The persistence is, by default, handled manually, but this can be overridden by setting the `BindingMode` to `CONTINUOUS` on the form level.\n\n## Localisation\n\nAll displayed values are localisable. Methods like `label()`, `placeholder()` accept keys which are then used for translation. By default, FormsFX includes a `ResourceBundle`-based implementation, however, this can be exchanged for a custom implementation.\n\n```java\nprivate ResourceBundle rbDE = ResourceBundle.getBundle(\"demo.demo-locale\", new Locale(\"de\", \"CH\"));\nprivate ResourceBundle rbEN = ResourceBundle.getBundle(\"demo.demo-locale\", new Locale(\"en\", \"UK\"));\n\nprivate ResourceBundleService rbs = new ResourceBundleService(rbEN);\n\nForm.of(…)\n        .i18n(rbs);\n```\n\n## Validation\n\nAll fields are validated whenever end users edit the contained data. FormsFX offers a wide range of pre-defined validators, but also includes support for custom validators using the `CustomValidator.forPredicate()` method.\n\n| Validator | Description |\n| --------- | ----------- |\n| `CustomValidator` | Define a predicate that returns whether the field is valid or not. |\n| `DoubleRangeValidator` | Define a number range which is considered valid. This range can be limited in either one direction or in both directions. |\n| `IntegerRangeValidator` | Define a number range which is considered valid. This range can be limited in either one direction or in both directions. |\n| `RegexValidator` | Valiate text against a regular expression. This validator offers pre-defined expressions for common use cases, such as email addresses.\n| `SelectionLengthValidator` | Define a length interval which is considered valid. This range can be limited in either one direction or in both directions. |\n| `StringLengthValidator` | Define a length interval which is considered valid. This range can be limited in either one direction or in both directions. |\n\n## Advantages\n\n- Less error-prone\n- Less code needed\n- Easy to learn\n- Easy to understand\n- Easy to extend\n\n# Documentation\n\n- [Javadocs](http://dlsc.com/wp-content/html/formsfx/apidocs/)\n- [Report](./docs/Project%20Report.pdf)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlemmermann%2FFormsFX","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdlemmermann%2FFormsFX","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlemmermann%2FFormsFX/lists"}