Showing preview only (410K chars total). Download the full file or copy to clipboard to get everything.
Repository: dlemmermann/formsfx
Branch: master-11
Commit: 29986f26d448
Files: 101
Total size: 375.7 KB
Directory structure:
gitextract_xva4uep3/
├── .github/
│ └── workflows/
│ ├── build.yml
│ └── release.yml
├── .gitignore
├── .mvn/
│ └── wrapper/
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── CHANGELOG.md
├── LICENSE
├── README.md
├── docs/
│ ├── Project Report.pages/
│ │ └── Metadata/
│ │ ├── BuildVersionHistory.plist
│ │ ├── DocumentIdentifier
│ │ └── Properties.plist
│ ├── architecture.xml
│ ├── controls.sketch
│ ├── grid.sketch
│ └── work.sketch
├── formsfx-core/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ ├── license/
│ │ ├── apache20/
│ │ │ ├── header.txt
│ │ │ └── license.txt
│ │ └── licenses.properties
│ ├── main/
│ │ ├── java/
│ │ │ ├── com/
│ │ │ │ └── dlsc/
│ │ │ │ └── formsfx/
│ │ │ │ ├── model/
│ │ │ │ │ ├── event/
│ │ │ │ │ │ ├── FieldEvent.java
│ │ │ │ │ │ ├── FormEvent.java
│ │ │ │ │ │ └── GroupEvent.java
│ │ │ │ │ ├── structure/
│ │ │ │ │ │ ├── BooleanField.java
│ │ │ │ │ │ ├── DataField.java
│ │ │ │ │ │ ├── DateField.java
│ │ │ │ │ │ ├── DoubleField.java
│ │ │ │ │ │ ├── Element.java
│ │ │ │ │ │ ├── Field.java
│ │ │ │ │ │ ├── Form.java
│ │ │ │ │ │ ├── FormElement.java
│ │ │ │ │ │ ├── Group.java
│ │ │ │ │ │ ├── IntegerField.java
│ │ │ │ │ │ ├── MultiSelectionField.java
│ │ │ │ │ │ ├── NodeElement.java
│ │ │ │ │ │ ├── PasswordField.java
│ │ │ │ │ │ ├── Section.java
│ │ │ │ │ │ ├── SelectionField.java
│ │ │ │ │ │ ├── SingleSelectionField.java
│ │ │ │ │ │ └── StringField.java
│ │ │ │ │ ├── util/
│ │ │ │ │ │ ├── BindingMode.java
│ │ │ │ │ │ ├── ResourceBundleService.java
│ │ │ │ │ │ ├── TranslationService.java
│ │ │ │ │ │ └── ValueTransformer.java
│ │ │ │ │ └── validators/
│ │ │ │ │ ├── CustomValidator.java
│ │ │ │ │ ├── DoubleRangeValidator.java
│ │ │ │ │ ├── IntegerRangeValidator.java
│ │ │ │ │ ├── RegexValidator.java
│ │ │ │ │ ├── RootValidator.java
│ │ │ │ │ ├── SelectionLengthValidator.java
│ │ │ │ │ ├── StringLengthValidator.java
│ │ │ │ │ ├── ValidationResult.java
│ │ │ │ │ └── Validator.java
│ │ │ │ └── view/
│ │ │ │ ├── controls/
│ │ │ │ │ ├── SimpleBooleanControl.java
│ │ │ │ │ ├── SimpleCheckBoxControl.java
│ │ │ │ │ ├── SimpleComboBoxControl.java
│ │ │ │ │ ├── SimpleControl.java
│ │ │ │ │ ├── SimpleDateControl.java
│ │ │ │ │ ├── SimpleDoubleControl.java
│ │ │ │ │ ├── SimpleIntegerControl.java
│ │ │ │ │ ├── SimpleListViewControl.java
│ │ │ │ │ ├── SimpleNumberControl.java
│ │ │ │ │ ├── SimplePasswordControl.java
│ │ │ │ │ ├── SimpleRadioButtonControl.java
│ │ │ │ │ └── SimpleTextControl.java
│ │ │ │ ├── renderer/
│ │ │ │ │ ├── FormRenderer.java
│ │ │ │ │ ├── GroupRenderer.java
│ │ │ │ │ ├── GroupRendererBase.java
│ │ │ │ │ └── SectionRenderer.java
│ │ │ │ └── util/
│ │ │ │ ├── ColSpan.java
│ │ │ │ └── ViewMixin.java
│ │ │ └── module-info.java
│ │ └── resources/
│ │ └── com/
│ │ └── dlsc/
│ │ └── formsfx/
│ │ └── view/
│ │ └── renderer/
│ │ └── style.css
│ └── test/
│ ├── java/
│ │ └── com/
│ │ └── dlsc/
│ │ └── formsfx/
│ │ ├── model/
│ │ │ ├── structure/
│ │ │ │ ├── FieldTest.java
│ │ │ │ ├── FormTest.java
│ │ │ │ └── SectionTest.java
│ │ │ ├── util/
│ │ │ │ └── ResourceBundleServiceTest.java
│ │ │ └── validators/
│ │ │ ├── CustomValidatorTest.java
│ │ │ ├── DoubleRangeValidatorTest.java
│ │ │ ├── IntegerRangeValidatorTest.java
│ │ │ ├── RegexValidatorTest.java
│ │ │ ├── SelectionLengthValidatorTest.java
│ │ │ └── StringLengthValidatorTest.java
│ │ └── view/
│ │ ├── controls/
│ │ │ └── SimpleControlTest.java
│ │ └── renderer/
│ │ └── RendererTest.java
│ └── resources/
│ ├── testbundle_de_CH.properties
│ └── testbundle_en_UK.properties
├── formsfx-demo/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ └── main/
│ ├── java/
│ │ ├── com/
│ │ │ └── dlsc/
│ │ │ └── formsfx/
│ │ │ └── demo/
│ │ │ ├── Demo.java
│ │ │ ├── model/
│ │ │ │ ├── Country.java
│ │ │ │ └── DemoModel.java
│ │ │ └── view/
│ │ │ └── RootPane.java
│ │ └── module-info.java
│ └── resources/
│ ├── demo-locale_de_CH.properties
│ ├── demo-locale_en_UK.properties
│ └── style.css
├── jreleaser.yml
├── mvnw
├── mvnw.cmd
└── pom.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
push:
branches:
- master-11
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
name: Build
runs-on: ubuntu-latest
if: startsWith(github.event.head_commit.message, '🏁 Releasing version') != true
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 17
- name: Cache SonarCloud packages
uses: actions/cache@v1
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Maven packages
uses: actions/cache@v1
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
workflow_dispatch:
inputs:
version:
description: "Release version"
required: true
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: 'Set up Java'
uses: actions/setup-java@v2
with:
java-version: 14
distribution: 'zulu'
server-id: central
server-username: MAVEN_USERNAME
server-password: MAVEN_CENTRAL_TOKEN
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: 'Cache Maven packages'
uses: actions/cache@v2
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Update version
id: version
run: |
VERSION=${{ github.event.inputs.version }}
echo "Updating POMs to version $VERSION"
./mvnw -B versions:set versions:commit -DnewVersion=$VERSION
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "GitHub Action"
git commit -a -m "🏁 Releasing version $VERSION"
git push origin HEAD:master-11
- name: Release to Maven Central
env:
MAVEN_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
MAVEN_CENTRAL_TOKEN: ${{ secrets.SONATYPE_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: |
export GPG_TTY=$(tty)
./mvnw --no-transfer-progress -B --file pom.xml \
-Drepository.url=https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git \
-Dmaven.site.skip=true -Drelease=true deploy
- name: Release to GitHub
env:
JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./mvnw -B --file pom.xml -Prelease -pl :formsfx jreleaser:full-release
- name: JReleaser output
if: always()
uses: actions/upload-artifact@v2
with:
name: jreleaser-logs
path: |
target/jreleaser/trace.log
target/jreleaser/output.properties
================================================
FILE: .gitignore
================================================
.idea
/target
*.iml
/out
================================================
FILE: .mvn/wrapper/maven-wrapper.properties
================================================
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
================================================
FILE: CHANGELOG.md
================================================
# Change Log
## [11.4.1](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/11.4.1) (2019-09-01)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/8.4.0...11.4.1)
## [8.4.0](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/8.4.0) (2019-08-25)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/11.4.0...8.4.0)
## [11.4.0](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/11.4.0) (2019-08-25)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v11.3.2...11.4.0)
**Implemented enhancements:**
- Add Continuous Delivery to Maven Central [\#47](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/47) ([martinfrancois](https://github.com/martinfrancois))
## [v11.3.2](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v11.3.2) (2019-01-09)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v10.3.1...v11.3.2)
**Closed issues:**
- Date Field [\#39](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/39)
## [v10.3.1](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v10.3.1) (2019-01-09)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v11.3.1...v10.3.1)
## [v11.3.1](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v11.3.1) (2019-01-09)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v1.3.1...v11.3.1)
## [v1.3.1](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v1.3.1) (2019-01-09)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v11.3.0...v1.3.1)
**Closed issues:**
- JDK 11 compatible [\#38](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/38)
**Merged pull requests:**
- New DateField support. [\#42](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/42) ([dlemmermann](https://github.com/dlemmermann))
- New Field - DatePicker [\#40](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/40) ([pershy](https://github.com/pershy))
## [v11.3.0](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v11.3.0) (2018-09-17)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v10.3.0...v11.3.0)
## [v10.3.0](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v10.3.0) (2018-09-17)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v1.3.0...v10.3.0)
## [v1.3.0](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v1.3.0) (2018-09-06)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v1.2.1...v1.3.0)
**Implemented enhancements:**
- PasswordFields [\#7](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/7)
**Closed issues:**
- Required field fails when I18N is enabled [\#32](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/32)
- DataField assumes edited value can be transformed to a suitable String representation [\#30](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/30)
- Open SimpleControl impls for extension [\#27](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/27)
- Trigger an event when Form is persisted/reset [\#25](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/25)
- Embed additional content inside a Group/Section [\#23](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/23)
- Support additional descriptions on Field [\#18](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/18)
- Section.title should return Section [\#15](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/15)
- Allow SectionRenderer.titledPane.collapsible to be set [\#13](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/13)
- Add custom style-class to Form/Section renderers [\#12](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/12)
- Update codebase with fixes from PreferencesFX [\#11](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/11)
**Merged pull requests:**
- Use StringConverter instead of ValueTransformer in DataField [\#34](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/34) ([aalmiray](https://github.com/aalmiray))
- Check against empty requiredError instead of null [\#33](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/33) ([aalmiray](https://github.com/aalmiray))
- Enable additional content inside Form/Section/Group [\#29](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/29) ([aalmiray](https://github.com/aalmiray))
- Extension points [\#28](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/28) ([aalmiray](https://github.com/aalmiray))
- Add event handlers to Form/Group/Field [\#26](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/26) ([aalmiray](https://github.com/aalmiray))
- Additional description support for label/value [\#21](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/21) ([aalmiray](https://github.com/aalmiray))
- Fix fluent interface methods in Section [\#17](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/17) ([aalmiray](https://github.com/aalmiray))
- Add a collapsible property to Section [\#16](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/16) ([aalmiray](https://github.com/aalmiray))
- Add style classes to FormRenderer and SectionRenderer [\#14](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/14) ([aalmiray](https://github.com/aalmiray))
- PasswordField support [\#10](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/10) ([aalmiray](https://github.com/aalmiray))
## [v1.2.1](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v1.2.1) (2018-04-30)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v1.2-2...v1.2.1)
## [v1.2-2](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v1.2-2) (2018-04-27)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v1.2...v1.2-2)
## [v1.2](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v1.2) (2018-04-27)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v1.1...v1.2)
**Fixed bugs:**
- Single Selection Type Fields Not Persisting [\#2](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/2)
**Closed issues:**
- Any plans to publish the project to Maven? [\#5](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/5)
**Merged pull requests:**
- Fix dependency issues [\#8](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/8) ([martinfrancois](https://github.com/martinfrancois))
## [v1.1](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v1.1) (2017-12-06)
[Full Changelog](https://github.com/dlsc-software-consulting-gmbh/formsfx/compare/v1.0...v1.1)
**Merged pull requests:**
- Bugfixing and Changes of Visibility for Inheritance [\#6](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/6) ([martinfrancois](https://github.com/martinfrancois))
## [v1.0](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/v1.0) (2017-09-26)
**Closed issues:**
- Make Field Instance Variable Protected In SimpleControl [\#3](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/3)
- add license [\#1](https://github.com/dlsc-software-consulting-gmbh/formsfx/issues/1)
**Merged pull requests:**
- adds default encoding for project [\#4](https://github.com/dlsc-software-consulting-gmbh/formsfx/pull/4) ([rladstaetter](https://github.com/rladstaetter))
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
[](https://www.jfx-central.com/libraries/formsfx)
# FormsFX
**Forms for business application made easy. Creating forms in Java has never been this easy!**
## Maven
To use this framework as part of your Maven build simply add the following dependency to your pom.xml file.
```XML
<dependency>
<groupId>com.dlsc.formsfx</groupId>
<artifactId>formsfx-core</artifactId>
<version>11.3.2</version>
</dependency>
```
## What is FormsFX?
Creating 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*.
## Main Features
- Simple and understandable Fluent API
- Different semantic items
- Pre-defined controls
- Validation
- Localisation
```Java
Form loginForm = Form.of(
Group.of(
Field.ofStringType(model.usernameProperty())
.label("Username"),
Field.ofStringType(model.passwordProperty())
.label("Password")
.required("This field can’t be empty")
)
).title("Login");
```
## Semantics
FormsFX 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.
## Defining a form
Creating a form is as simple as calling `Form.of()`.
```Java
Form.of(
Group.of(
Field.ofStringType("")
.label("Username"),
Field.ofStringType("")
.label("Password")
.required("This field can’t be empty")
),
Group.of(…)
).title("Login");
```
Fields have a range of options that define their semantics and change their functionality.
Option | Description
------ | -----------
`label(String)` | Describes the field’s content in a concise manner. This description is always visible and usually placed next to the editable control.
`tooltip(String)` | This contextual hint further describes the field. It is usually displayed on hover or focus.
`placeholder(String)` | This hint describes the expected input as long as the field is empty.
`required(boolean)` <br /> `required(String)` | Determines, whether entry in this field is required for the correctness of the form.
`editable(boolean)` | Determines, whether end users can edit the contents of this field.
`id(String)` | Describes the field with a unique ID. This is not visible directly, but can be used for styling purposes.
`styleClass(List<String>)` | Adds styling hooks to the field. This can be used on the view layer.
`span(int)` <br /> `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.
`render(SimpleControl)` | Determines the control that is used to render this field on the view layer.
The following table shows how to create different fields and how they look by default:
String Control
<table>
<tbody>
<tr>
<td colspan="2">String Control</td>
</tr>
<tr>
<td><img src="./docs/images/StringField.png" /></td>
</tr>
<tr>
<td>
<pre lang="java">Field.ofStringType("CHF")
.label("Currency")</pre>
</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td colspan="2">Integer Control</td>
</tr>
<tr>
<td><img src="./docs/images/IntegerField.png" /></td>
</tr>
<tr>
<td>
<pre lang="java">Field.ofIntegerType(8401120)
.label("Population")</pre>
</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td colspan="2">Double Control</td>
</tr>
<tr>
<td><img src="./docs/images/DoubleField.png" /></td>
</tr>
<tr>
<td>
<pre lang="java">Field.ofDoubleType(41285.0)
.label("Area")</pre>
</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td colspan="2">Boolean Control</td>
</tr>
<tr>
<td><img src="./docs/images/BooleanField.png" /></td>
</tr>
<tr>
<td>
<pre lang="java">Field.ofBooleanType(false)
.label("Independent")</pre>
</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td colspan="2">ComboBox Control</td>
</tr>
<tr>
<td><img src="./docs/images/ComboBoxField.png" /></td>
</tr>
<tr>
<td>
<pre lang="java">Field.ofSingleSelectionType(Arrays.asList("Zürich (ZH)", "Bern (BE)", …), 1)
.label("Capital")</pre>
</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td colspan="2">RadioButton Control</td>
</tr>
<tr>
<td><img src="./docs/images/RadioButtonField.png" /></td>
</tr>
<tr>
<td>
<pre lang="java">Field.ofSingleSelectionType(Arrays.asList("Right", "Left"), 0)
.label("Driving on the")
.render(new SimpleRadioButtonControl<>())</pre>
</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td colspan="2">CheckBox Control</td>
</tr>
<tr>
<td><img src="./docs/images/CheckBoxField.png" /></td>
</tr>
<tr>
<td>
<pre lang="java">Field.ofMultiSelectionType(Arrays.asList("Africa", "Asia", …), Collections.singletonList(2))
.label("Continent")
.render(new SimpleCheckBoxControl<>())</pre>
</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td colspan="2">ListView Control</td>
</tr>
<tr>
<td><img src="./docs/images/ListField.png" /></td>
</tr>
<tr>
<td>
<pre lang="java">Field.ofMultiSelectionType(Arrays.asList("Zürich (ZH)", "Bern (BE)", …), Arrays.asList(0, 1, …))
.label("Biggest Cities")</pre>
</td>
</tr>
</tbody>
</table>
## Rendering a form
The only point of interaction is the `FormRenderer`. It delegates rendering of further components to other renderers.
```java
Pane root = new Pane();
root.getChildren().add(new FormRenderer(form));
```
All fields have a default control that is used for rendering. This can be changed to another compatible implementation using the `render()` method.
```java
Field.ofMultiSelectionType(…)
.render(new SimpleCheckBoxControl<>())
```
## Model
Forms 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.
```java
StringProperty name = new SimpleStringProperty("Hans");
Field.ofStringType(name);
```
The `persist()` and `reset()` methods can be used to store and revert field values, which in turn updates the binding.
Fields 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.
## Localisation
All 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.
```java
private ResourceBundle rbDE = ResourceBundle.getBundle("demo.demo-locale", new Locale("de", "CH"));
private ResourceBundle rbEN = ResourceBundle.getBundle("demo.demo-locale", new Locale("en", "UK"));
private ResourceBundleService rbs = new ResourceBundleService(rbEN);
Form.of(…)
.i18n(rbs);
```
## Validation
All 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.
| Validator | Description |
| --------- | ----------- |
| `CustomValidator` | Define a predicate that returns whether the field is valid or not. |
| `DoubleRangeValidator` | Define a number range which is considered valid. This range can be limited in either one direction or in both directions. |
| `IntegerRangeValidator` | Define a number range which is considered valid. This range can be limited in either one direction or in both directions. |
| `RegexValidator` | Valiate text against a regular expression. This validator offers pre-defined expressions for common use cases, such as email addresses.
| `SelectionLengthValidator` | Define a length interval which is considered valid. This range can be limited in either one direction or in both directions. |
| `StringLengthValidator` | Define a length interval which is considered valid. This range can be limited in either one direction or in both directions. |
## Advantages
- Less error-prone
- Less code needed
- Easy to learn
- Easy to understand
- Easy to extend
# Documentation
- [Javadocs](http://dlsc.com/wp-content/html/formsfx/apidocs/)
- [Report](./docs/Project%20Report.pdf)
================================================
FILE: docs/Project Report.pages/Metadata/BuildVersionHistory.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>Template: Blank (2015-09-16 11:13)</string>
<string>M5.6.2-2573-1</string>
<string>M6.0-3507-1</string>
<string>M5.6.2-2573-1</string>
<string>M6.0.5-4052-1</string>
<string>M5.6.2-2573-1</string>
<string>M6.0.5-4052-1</string>
<string>M5.6.2-2573-1</string>
<string>M6.0.5-4052-1</string>
<string>M5.6.2-2573-1</string>
<string>M6.0.5-4052-1</string>
<string>M6.1-4328-1</string>
<string>M6.1.1-4338-1</string>
<string>G-r13-2C85</string>
<string>M6.2-4582-1</string>
<string>G-r13-2C85</string>
<string>M6.2-4582-1</string>
</array>
</plist>
================================================
FILE: docs/Project Report.pages/Metadata/DocumentIdentifier
================================================
A198DE43-9C62-4C8D-9A85-4BBB04C88780
================================================
FILE: docs/architecture.xml
================================================
<mxfile userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30" version="6.9.5" editor="www.draw.io" type="device"><diagram id="5cf761be-5104-c127-7bda-1d032f754fbc" name="Page-1">3Zxfk6I4EMA/ja9bQPj7eOPM7F3VbtWWbt3tPWYkC9mJxIpx1Pv0FyUoIci4I0TAl4EmQtL969CdjjMB0+XuM4Or9CuNEZk4VrybgMeJ49guCMWfg2SfSyLLzwUJw3Euss6COf4PyW8W0g2O0VrKchGnlHC8UoULmmVowRUZZIxu1WY/KYkVwQomSBPMF5Do0n9wzFMptf3ofOFPhJO0eLTvufmVF7h4TRjdZPKBEwf8PH7yy0tY3EyOdJ3CmG5LIvA0AVNGKc+PlrspIgflqnp7vnD11HGGMn7NF4Aj+8H3xeBRLHQhTynjKU1oBsnTWfpwHB863MESZylfEnFoi0PxULb/UT7599Dok+OJ8zWHjP9xsI6QZTRDhewZEyLvhbK4aBFjuKRZ/D3FWX6h1OwX4nwvsYEbToXo3NMvlK5kF9ac0Vc0pYSy49iAdfyIK/moD0O9qDgpWtMNW8hWUlmi0wmSrZzwZDXhDogukRi1aMMQgRy/qbeHksvk1E5+VQwa7ksNVhRnfF2687eDQDSQLub6QX5H6WDA9lQzv9c+VLAQB3kPirPSUM6iIzr1GEnFvEGykSN+pmypoaWCs00xR/MVPGp3K2YSFSZIcCJM/7gQFkHsZLM3xDjaNVtNN0ehh0jVgxPmerO2JTcvfDMtebhvXbZgSYuNSgKgTV/rlTtdcnzvw64GunI13Tc8lQnX99Rb5H2Q3zqb+7d91qr4YPSOzza3v9lngeaznwVsqz46baQqwjfotE6rTtvkJ7/p0C+ELl5782Z0dXcFN3rrtRZyNY7nIibENOsfyb5/R5KBa4LkYCShntfB++daS3ntBuU7zH8UShfHJTudjJjPQGczDn06qrEe8NqIHm4N1N2oko+9095zm4MEEDS2vzlI8LTJ9RkjkU33bmqtBgmua3BqtY1MrYMPEnzdK291ymst5GscP0IOe8pyNUwwy7LXCcuVN8wHMth+sRzcj+VAY3mOSB7y9hTo6uTsOSYzOL+TaEpGUEVApbLujAv2UIc9MAR7qMOOs4Sg3iPvqIGZb5lEPugGeacB+WBcyEf3Qz7SkP+6IRz3nXivErUYJd4OO4laxhaBFwXWMta+IayLZ5encs7EZN5TnkO3krobjcKjTmZwZQmosgI0sgncLjYOtIj6h5aAAq8S/HrtLtEUAy3ntnTzQtBA/MpsMmBpCunar0bmVs4d3yCORvpfgssEsYGgbjYJsDWFdI36yNJeu2YTgjHW9fL8A6UEwb6G/xrrJrfWhPo7sE34FYrVamUDzBL3frBct4ZjqkJfs4jzncFsfXgMzeaIvWHRzd4RDezKBhyj1fpWA5VBT8N1azHGavE1qzEzlPfuQSj7sBA5EHyN5q9uXyuil/aa2HcEHNRsV3BNTc5AL/HPKOV/CyRjyMUIewi2o0YakUmw2y2PnpbWG1bWxxVUg5pdADfvzbkadn0fwHSz5nQ5INyDwCTu3VSSLieRY1txBzUbBYCpJBLUbBU4Lrl/QVnC0x5DX90xYBb6bopJo1tiB3U5pTG29aRyhhK0GxDUoWcS6nYrSqMNT2qSTXNM68lmXsqZwSxBAyI7AgbJ9tqt6Yx2OdutKf4bQ9vVq/+ydjM0tm3LNgl3u1WcFn+g3TO4a8r9N8P9oXq/61byNeed33lW26s/Ebl5f0Chmbr9woPLA8yu9eg1OKkqoboZWm8I75/GbBAY05g4Pf+rihzN8z8EAU//Aw==</diagram><diagram id="2878d1a8-c243-3bc8-e21e-b7c19a7684b3" name="Page-2">3VdNb9swDP01vg62lGTpcc3SbcB2WYatPaoWa2uVxUCRm2S/fpIl+QNOigILmnRGDuSjPsjHF8JO6KLafdJsXX5DDjIhKd8l9GNCyJyQxP1SvvfANJt7oNCCeyjtgJX4Ax7MIloLDpuAecggSiPWQzBHpSA3A4xpjdvhsgeUfACsWQEjYJUzOUZ/CW7KWNaswz+DKMp4cza78pF7lj8WGmsV7ksIfWgeH65YPCsUuikZx20PosuELjSi8Va1W4B01A5puzkSbfPWoMyLNkz8jicma4gpN4mZfSSjKQfchjSh19tSGFitWe6iW9t9i5WmktbLrMmkKJS1c5sAaAuE80Eb2B1NMmtLt4oCrMDovV0SNhAa2Apqyt4Hf9v1JpsHrOz1hUSQBT0U7dkdJ9YItByhiL4Biibzc1JERgx9B8uHttVdHFNkNmSqJaDPFDnA1OwUWhpLB7idPMFFbUosUDG57NDrIWU9emAnzG2AnX3n7HdT5ymb2G1c5pwutjFMmw9uSFqIC1ah4j9KoWLoRsj2AsXjQoUKPBLi7tLfYMw+TG9WG7RQV8JXxHU4Z2M0PsICJeqmaJo2T9tQx8Hz7bSUYa3zsCr8I222BUQdH266BsmMeBqe/i8dHA+DldF1bmoNl6f1aXZGrc9PKvUo6J6+78KyFwo6vWBBT8aCpq8k6PELwBcnQGVvcUWLTWNcvrazq9ec4+mIkFPMca/tOMmfkX32f8h+ej7ZT0ey/2lVyt+I2Omh17sTid263fdHE+t949HlXw==</diagram><diagram id="1a86d444-8032-98fa-018f-ab649ec67932" name="Page-3">3Zpdb5swFIZ/TS5XgQGTXi7pxyZ109RMW3vpgAtegIMc0yT79TPBBAihyqRCTLkJvPjz+DkHjsnEmsfbe07S8Bv4NJogw99OrJsJkge25U+u7Arl2sCFEHDmF5JRCQv2lxaiWaoZ8+laaYUkACLB0qboQZJQTzQ0wjlsmsVeIPIbQkoC2hIWHona6m/mi7BQpwhX+hfKgrDs2cTXxZ0l8VYBhyxR/U2Q9bI/itsxKdtSE12HxIdNTbJuJ9acA4jiLN7OaZTbtmm2u467h3FzmohzKqCiwiuJMjX1O+DxI018yilXYxS70i77mdG8rjGxZpuQCbpIiZff3UgSpBaKOJJXpjwlEQsSee7Jsci2rJnqi3JBt53jNQ9WkHRRiKngO1lEVfjkWspyiiwbqzXZVOtkltYNa2uElUYUGsGh7co88kRZ6LS1rJa17qVF0tJcM7KmIzCZYzvDmcxuGYT60tXUJXARQgAJiW4rddY0Wc08dMvEUy5fIUddPqtS0hh8V9xznfL6WdVbC8LF5zwuSCGBhJbaHcsHrhrwyxLLCLxVIdUK/KFC7FSoIpkAKVXDfwBID51xWNE5RMD3E7aM/XFYzHz+jaVcQ8Y9JamVkWMLqGhAd8aCcxoRwV6brZ9aPFX1BzDZYgUKtpugYMNptlEMS1WrGJB2I7tasTQvsP6fjtS8K6aKJivCDrM8Czqn5acL+ZRgkGgc2DA+bZNBvBT346XuG16KRuyl7iW91DUG8tJWR+/spe7bT1MNfXTaYZFBfHTaDmosTiPJsHQiiDQ0l2VZl3vxuO4jpJn1eHblNCJaPZyp8DaeiFYmXvWQNn3/kHbu4pXDacH+wNbiF6MbfaF3jCb0gyYoptmyyKDUjwx6pBf07WRcRfiQeqsZbMcD/aCR3rQuC707Muptvai3O6ifAUSUJOOBHqMhI73TB/QK9FrGNiKusV5c4w6uv2fxknJ9sT5+ax8Wa7cfrD/qfqE5bUNv4rPX/P2p78pSv0pCA52xR7iJvWsOiX0v2erH3YBDJ9LVS2KPuvLVG8iWOm/R2OWH2UtQj3rJVo3uF3dz1Hs0SK90tRxOi/mfdCv0Jd7Ex/szA6aqqJdU9XziRwa8Xpkq6spU5xAvQev9mWPoB92fQf2kqmdDP7L9GaRXHou68thH4jOYZUKAxns0x+D3+cVOXlZ/3Cq+h1b/jrNu/wE=</diagram></mxfile>
================================================
FILE: formsfx-core/.gitignore
================================================
/target
*.iml
================================================
FILE: formsfx-core/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dlsc.formsfx</groupId>
<artifactId>formsfx-core</artifactId>
<packaging>jar</packaging>
<version>11.6.0</version>
<name>FormsFX Core</name>
<description>A framework for quickly creating form-based UIs.</description>
<url>https://github.com/dlemmermann/formsfx</url>
<parent>
<groupId>com.dlsc.formsfx</groupId>
<artifactId>formsfx</artifactId>
<version>11.6.0</version>
</parent>
<licenses>
<license>
<name>Apache 2.0</name>
</license>
</licenses>
<scm>
<url>https://github.com/dlemmermann/formsfx</url>
</scm>
<developers>
<developer>
<name>Dirk Lemmermann</name>
<url>http://www.dlsc.com</url>
<organization>DLSC Software & Consulting</organization>
</developer>
</developers>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<failOnError>false</failOnError>
<force>true</force>
<windowtitle>FormsFX API</windowtitle>
<additionalJOptions>
<additionalJOption>-J-Djavafx.javadoc=true</additionalJOption>
<additionalJOption>-html5</additionalJOption>
</additionalJOptions>
<docfilessubdirs>true</docfilessubdirs>
<tags>
<tag>
<name>defaultValue</name>
<placement>a</placement>
<head>Default Value:</head>
</tag>
<tag>
<name>apiNote</name>
<placement>a</placement>
<head>API Note:</head>
</tag>
<tag>
<name>implSpec</name>
<placement>a</placement>
<head>Implementation Requirements:</head>
</tag>
<tag>
<name>implNote</name>
<placement>a</placement>
<head>Implementation Note:</head>
</tag>
</tags>
<sourceFileExcludes>
<sourceFileExclude>**\/\module-info.java</sourceFileExclude>
</sourceFileExcludes>
</configuration>
<dependencies>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>make-docs
</id> <!-- this is used for inheritance merges -->
<phase>package
</phase> <!-- bind to the packaging phase -->
<goals>
<goal>aggregate</goal>
</goals>
</execution>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>1.16</version>
<configuration>
<licenseName>apache20</licenseName>
<licenseResolver>${project.baseUri}/src/license
</licenseResolver>
<organizationName>DLSC Software & Consulting GmbH
</organizationName>
<inceptionYear>2019</inceptionYear>
<projectName>FormsFX</projectName>
<processStartTag>
========================LICENSE_START=================================
</processStartTag>
<processEndTag>
=========================LICENSE_END==================================
</processEndTag>
<verbose>false</verbose>
<includes>
<includes>**/*.java</includes>
</includes>
</configuration>
<executions>
<execution>
<id>first</id>
<goals>
<goal>update-file-header</goal>
</goals>
<phase>process-sources</phase>
<configuration>
<roots>
<root>src/main/java</root>
<root>src/test/java</root>
</roots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
================================================
FILE: formsfx-core/src/license/apache20/header.txt
================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: formsfx-core/src/license/apache20/license.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: formsfx-core/src/license/licenses.properties
================================================
apache20=Apache License 2.0
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/event/FieldEvent.java
================================================
package com.dlsc.formsfx.model.event;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 - 2018 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.structure.Field;
import javafx.event.Event;
import javafx.event.EventType;
/**
* Identifies events triggered by a {@code Field}.
*
* @author Andres Almiray
*/
public final class FieldEvent extends Event {
/**
* When a {@code Field} is persisted.
*/
public static final EventType<FieldEvent> EVENT_FIELD_PERSISTED = new EventType<>(ANY, "EVENT_FIELD_PERSISTED");
/**
* When a {@code Field} is reset.
*/
public static final EventType<FieldEvent> EVENT_FIELD_RESET = new EventType<>(ANY, "EVENT_FIELD_RESET");
/**
* Creates a new instance of {@code FieldEvent} with event type set to {@code EVENT_FIELD_PERSISTED}.
*/
public static FieldEvent fieldPersistedEvent(Field field) {
return new FieldEvent(EVENT_FIELD_PERSISTED, field);
}
/**
* Creates a new instance of {@code FieldEvent} with event type set to {@code EVENT_FIELD_RESET}.
*/
public static FieldEvent fieldResetEvent(Field field) {
return new FieldEvent(EVENT_FIELD_RESET, field);
}
private final Field field;
private FieldEvent(EventType<? extends Event> eventType, Field field) {
super(eventType);
this.field = field;
}
public final Field getField() {
return field;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/event/FormEvent.java
================================================
package com.dlsc.formsfx.model.event;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 - 2018 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.structure.Form;
import javafx.event.Event;
import javafx.event.EventType;
/**
* Identifies events triggered by a {@code Form}.
*
* @author Andres Almiray
*/
public final class FormEvent extends Event {
/**
* When a {@code Form} is persisted.
*/
public static final EventType<FormEvent> EVENT_FORM_PERSISTED = new EventType<>(ANY, "EVENT_FORM_PERSISTED");
/**
* When a {@code Form} is reset.
*/
public static final EventType<FormEvent> EVENT_FORM_RESET = new EventType<>(ANY, "EVENT_FORM_RESET");
/**
* Creates a new instance of {@code FormEvent} with event type set to {@code EVENT_FORM_PERSISTED}.
*/
public static FormEvent formPersistedEvent(Form form) {
return new FormEvent(EVENT_FORM_PERSISTED, form);
}
/**
* Creates a new instance of {@code FormEvent} with event type set to {@code EVENT_FORM_RESET}.
*/
public static FormEvent formResetEvent(Form form) {
return new FormEvent(EVENT_FORM_RESET, form);
}
private final Form form;
private FormEvent(EventType<? extends Event> eventType, Form form) {
super(eventType);
this.form = form;
}
public final Form getForm() {
return form;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/event/GroupEvent.java
================================================
package com.dlsc.formsfx.model.event;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 - 2018 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.structure.Group;
import javafx.event.Event;
import javafx.event.EventType;
/**
* Identifies events triggered by a {@code Group}.
*
* @author Andres Almiray
*/
public final class GroupEvent extends Event {
/**
* When a {@code Group} is persisted.
*/
public static final EventType<GroupEvent> EVENT_GROUP_PERSISTED = new EventType<>(ANY, "EVENT_GROUP_PERSISTED");
/**
* When a {@code Group} is reset.
*/
public static final EventType<GroupEvent> EVENT_GROUP_RESET = new EventType<>(ANY, "EVENT_GROUP_RESET");
/**
* Creates a new instance of {@code GroupEvent} with event type set to {@code EVENT_GROUP_PERSISTED}.
*/
public static GroupEvent groupPersistedEvent(Group group) {
return new GroupEvent(EVENT_GROUP_PERSISTED, group);
}
/**
* Creates a new instance of {@code GroupEvent} with event type set to {@code EVENT_GROUP_RESET}.
*/
public static GroupEvent groupResetEvent(Group group) {
return new GroupEvent(EVENT_GROUP_RESET, group);
}
private final Group group;
private GroupEvent(EventType<? extends Event> eventType, Group group) {
super(eventType);
this.group = group;
}
public final Group getGroup() {
return group;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/BooleanField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.view.controls.SimpleBooleanControl;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.util.StringConverter;
/**
* This class provides an implementation of a {@link Field} containing a
* {@code boolean} value.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class BooleanField extends DataField<BooleanProperty, Boolean, BooleanField> {
/**
* The constructor of {@code BooleanField}.
*
* @param valueProperty
* The property that is used to store the current valid value
* of the field.
* @param persistentValueProperty
* The property that is used to store the latest persisted
* value of the field.
*/
protected BooleanField(SimpleBooleanProperty valueProperty, SimpleBooleanProperty persistentValueProperty) {
super(valueProperty, persistentValueProperty);
stringConverter = new AbstractStringConverter<Boolean>() {
@Override
public Boolean fromString(String string) {
return Boolean.parseBoolean(string);
}
};
rendererSupplier = () -> new SimpleBooleanControl();
userInput.set(stringConverter.toString(value.getValue()));
}
/**
* {@inheritDoc}
*/
@Override
protected boolean validateRequired(String newValue) {
return !isRequired() || (isRequired() && newValue.equals("true"));
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/DataField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.event.FieldEvent;
import com.dlsc.formsfx.model.util.BindingMode;
import com.dlsc.formsfx.model.util.TranslationService;
import com.dlsc.formsfx.model.util.ValueTransformer;
import com.dlsc.formsfx.model.validators.ValidationResult;
import com.dlsc.formsfx.model.validators.Validator;
import javafx.beans.InvalidationListener;
import javafx.beans.binding.Bindings;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.util.StringConverter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* {@code DataField} holds a single value. This value can be represented and
* manipulated as a {@code String}. It is stored as a concrete type.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public abstract class DataField<P extends Property, V, F extends Field<F>> extends Field<F> {
/**
* Every field tracks its value in multiple ways.
*
* - The user input is bound to a specific control's input value and is a
* 1-to-1 representation of what the user enters.
* - The value is the last valid value entered by the user. This means that
* the value passes the type transformation of the concrete field and all
* user-defined validations.
* - The persistent value is the value that was last saved on the field. It
* is the responsibility of the form creator to persist the field values
* at the correct time.
*/
protected final P value;
protected final P persistentValue;
protected final StringProperty userInput = new SimpleStringProperty("");
/**
* Every field contains a list of validators. The validators are limited to
* the ones that correspond to the field's type.
*/
protected final List<Validator<V>> validators = new ArrayList<>();
/**
* The value transformer is responsible for transforming the user input
* string to the specific type of the field's value.
* @deprecated Use DataField#stringConverter instead.
*/
@Deprecated
ValueTransformer<V> valueTransformer;
protected StringConverter<V> stringConverter = new AbstractStringConverter<V>() {
@Override
public V fromString(String string) {
return null;
}
};
/**
* The format error is displayed when the value transformation fails.
*
* This property is translatable if a {@link TranslationService} is set on
* the containing form.
*/
protected final StringProperty formatErrorKey = new SimpleStringProperty("");
protected final StringProperty formatError = new SimpleStringProperty("");
/**
* This listener updates the field when the external binding changes.
*/
private final InvalidationListener externalBindingListener = (observable) -> userInput.setValue(stringConverter.toString((V) ((P) observable).getValue()));
/**
* Internal constructor for the {@code DataField} class. To create new
* elements, see the static factory methods in {@code Field}.
*
* @see Field::ofStringType
* @see Field::ofIntegerType
* @see Field::ofDoubleType
* @see Field::ofBooleanType
*
* @param valueProperty
* The property that is used to store the current valid value
* of the field.
* @param persistentValueProperty
* The property that is used to store the latest persisted
* value of the field.
*/
protected DataField(P valueProperty, P persistentValueProperty) {
value = valueProperty;
persistentValue = persistentValueProperty;
// The changed property is a binding that compares the persistent value
// with the current value. This means that a field is marked as changed
// until Field::persist or Field::reset are called or the value is back
// to the persistent value.
changed.bind(Bindings.createBooleanBinding(() -> !stringConverter.toString((V) persistentValue.getValue()).equals(userInput.getValue()), userInput, persistentValue));
// Whenever one of the translatable elements' keys change, update the
// displayed value based on the new translation.
formatErrorKey.addListener((observable, oldValue, newValue) -> formatError.setValue(translationService.translate(newValue)));
// Changes to the user input are reflected in the value only if the new
// user input is valid.
userInput.addListener((observable, oldValue, newValue) -> {
if (validate()) {
value.setValue(stringConverter.fromString(newValue));
}
});
}
protected static abstract class AbstractStringConverter<V> extends StringConverter<V> {
@Override
public String toString(V object) {
return String.valueOf(object);
}
}
private static class StringConverterAdapter<V> extends AbstractStringConverter<V> {
private final ValueTransformer<V> valueTransformer;
public StringConverterAdapter(ValueTransformer<V> valueTransformer) {
this.valueTransformer = valueTransformer;
}
@Override
public V fromString(String string) {
return valueTransformer.transform(string);
}
}
/**
* Sets the string converter for the current field.
*
* @param newValue
* The string converter that transforms the user input string to
* the field's underlying value and back.
*
* @return Returns the current field to allow for chaining.
*/
public F format(StringConverter<V> newValue) {
stringConverter = newValue;
validate();
return (F) this;
}
/**
* Applies a new string converter that converts the entered string input
* to a concrete value.
*
* @param newValue
* The string converter that transforms the user input string to
* the field's underlying value and back.
* @param errorMessage
* The error message to display if the transformation was
* unsuccessful.
*
* @return Returns the current field to allow for chaining.
*/
public F format(StringConverter<V> newValue, String errorMessage) {
stringConverter = newValue;
if (isI18N()) {
formatErrorKey.set(errorMessage);
} else {
formatError.set(errorMessage);
}
validate();
return (F) this;
}
/**
* Sets the value transformer for the current field.
*
* @param newValue
* The value transformer that parses the user input string to
* the field's underlying value.
*
* @return Returns the current field to allow for chaining.
* @deprecated Use format(StringConverter) instead
*/
@Deprecated
public F format(ValueTransformer<V> newValue) {
stringConverter = new StringConverterAdapter<>(newValue);
validate();
return (F) this;
}
/**
* Applies a new value transformer that converts the entered string input
* to a concrete value.
*
* @param newValue
* The new value transformer. Takes a string as an input and
* returns the concrete type.
* @param errorMessage
* The error message to display if the transformation was
* unsuccessful.
*
* @return Returns the current field to allow for chaining.
* @deprecated Use format(StringConverter, errorMessage) instead
*/
@Deprecated
public F format(ValueTransformer<V> newValue, String errorMessage) {
stringConverter = new StringConverterAdapter<>(newValue);
if (isI18N()) {
formatErrorKey.set(errorMessage);
} else {
formatError.set(errorMessage);
}
validate();
return (F) this;
}
/**
* Adds an error message to handle formatting errors with the default
* value transformers.
*
* @param errorMessage
* The error message to display if the transformation was
* unsuccessful.
*
* @return Returns the current field to allow for chaining.
*/
public F format(String errorMessage) {
if (isI18N()) {
formatErrorKey.set(errorMessage);
} else {
formatError.set(errorMessage);
}
validate();
return (F) this;
}
/**
* Sets the list of validators for the current field. This overrides all
* validators that have previously been added.
*
* @param newValue
* The validators that are to be used for validating this
* field. Limited to validators that are able to handle the
* field's underlying type.
*
* @return Returns the current field to allow for chaining.
*/
@SafeVarargs
public final F validate(Validator<V>... newValue) {
validators.clear();
Collections.addAll(validators, newValue);
validate();
return (F) this;
}
/**
* Binds the given property with the field.
*
* @param binding
* The property to be bound with.
*
* @return Returns the current field to allow for chaining.
*/
public F bind(P binding) {
persistentValue.bindBidirectional(binding);
binding.addListener(externalBindingListener);
return (F) this;
}
/**
* Unbinds the given property with the field.
*
* @param binding
* The property to be unbound with.
*
* @return Returns the current field to allow for chaining.
*/
public F unbind(P binding) {
persistentValue.unbindBidirectional(binding);
binding.removeListener(externalBindingListener);
return (F) this;
}
/**
* {@inheritDoc}
*/
public void setBindingMode(BindingMode newValue) {
if (BindingMode.CONTINUOUS.equals(newValue)) {
value.addListener(bindingModeListener);
} else {
value.removeListener(bindingModeListener);
}
}
/**
* Stores the field's current value in its persistent value. This stores
* the user's changes in the model.
*/
public void persist() {
if (!isValid()) {
return;
}
persistentValue.setValue(value.getValue());
fireEvent(FieldEvent.fieldPersistedEvent(this));
}
/**
* Sets the field's current value to its persistent value, thus resetting
* any changes made by the user.
*/
public void reset() {
if (!hasChanged()) {
return;
}
userInput.setValue(stringConverter.toString((V) persistentValue.getValue()));
}
/**
* Validates that the new field input matches the required condition.
*
* @param newValue
* The new value to check for the required state.
*
* @return Returns whether the input matches the required condition.
*/
protected boolean validateRequired(String newValue) {
return !isRequired() || (isRequired() && !newValue.isEmpty());
}
/**
* Validates a user input based on the field's value transformer and its
* validation rules. Also considers the {@code required} flag. This method
* directly updates the {@code valid} property.
*
* @return Returns whether the user input is a valid value or not.
*/
public boolean validate() {
String newValue = userInput.getValue();
if (!validateRequired(newValue)) {
if (isI18N() && !requiredErrorKey.get().isEmpty()) {
errorMessageKeys.setAll(requiredErrorKey.get());
} else if (!requiredError.get().isEmpty()) {
errorMessages.setAll(requiredError.get());
}
valid.set(false);
return false;
}
V transformedValue;
// Attempt a transformation from String to the field's underlying type.
try {
transformedValue = stringConverter.fromString(newValue);
} catch (Exception e) {
if (isI18N() && !formatErrorKey.get().isEmpty()) {
errorMessageKeys.setAll(formatErrorKey.get());
} else if (!formatError.get().isEmpty()) {
errorMessages.setAll(formatError.get());
}
valid.set(false);
return false;
}
// Check all validation rules and collect any error messages.
List<String> errorMessages = validators.stream()
.map(v -> v.validate(transformedValue))
.filter(r -> !r.getResult())
.map(ValidationResult::getErrorMessage)
.collect(Collectors.toList());
// Update the validation results with the current results. Listeners
// will handle the translation aspect.
if (isI18N()) {
errorMessageKeys.setAll(errorMessages);
} else {
this.errorMessages.setAll(errorMessages);
}
if (errorMessages.size() > 0) {
valid.set(false);
return false;
}
// If all above conditions have succeeded, the user input is
// considered valid.
valid.set(true);
return true;
}
/**
* {@inheritDoc}
*/
public void translate(TranslationService service) {
super.translate(service);
updateElement(formatError, formatErrorKey);
validate();
}
public String getUserInput() {
return userInput.get();
}
public StringProperty userInputProperty() {
return userInput;
}
public V getValue() {
return (V) value.getValue();
}
public P valueProperty() {
return value;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/DateField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 - 2018 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.view.controls.SimpleDateControl;
import javafx.beans.property.ObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.util.converter.LocalDateStringConverter;
import java.time.LocalDate;
import java.time.chrono.Chronology;
import java.time.format.FormatStyle;
import java.util.Locale;
/**
* This class provides an implementation of a {@link Field} containing a {@code LocalDate} value.
*
* @author Tomasz Krzemiński
*/
public class DateField extends DataField<ObjectProperty<LocalDate>, LocalDate, DateField> {
/**
* Internal constructor for the {@code DataField} class. To create new
* elements, see the static factory methods in {@code Field}.
*
* @param valueProperty The property that is used to store the current valid value
* of the field.
* @param persistentValueProperty The property that is used to store the latest persisted
* @see Field ::ofStringType
* @see Field ::ofIntegerType
* @see Field ::ofDoubleType
* @see Field ::ofBooleanType
*/
public DateField(ObjectProperty<LocalDate> valueProperty, ObjectProperty<LocalDate> persistentValueProperty) {
super(valueProperty, persistentValueProperty);
Chronology chronology = Chronology.ofLocale(Locale.getDefault(Locale.Category.FORMAT));
stringConverter = new LocalDateStringConverter(FormatStyle.SHORT, null, chronology);
rendererSupplier = () -> new SimpleDateControl();
userInput.setValue(null);
userInput.setValue(stringConverter.toString((LocalDate) persistentValue.getValue()));
}
@Override
public DateField bind(ObjectProperty<LocalDate> binding) {
return super.bind(binding);
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/DoubleField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.view.controls.SimpleDoubleControl;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
/**
* This class provides an implementation of a {@link Field} containing a
* {@code double} value.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class DoubleField extends DataField<DoubleProperty, Double, DoubleField> {
/**
* The constructor of {@code DoubleField}.
*
* @param valueProperty
* The property that is used to store the current valid value
* of the field.
* @param persistentValueProperty
* The property that is used to store the latest persisted
* value of the field.
*/
protected DoubleField(SimpleDoubleProperty valueProperty, SimpleDoubleProperty persistentValueProperty) {
super(valueProperty, persistentValueProperty);
stringConverter = new AbstractStringConverter<Double>() {
@Override
public Double fromString(String string) {
return Double.parseDouble(string);
}
};
rendererSupplier = () -> new SimpleDoubleControl();
userInput.set(stringConverter.toString(value.getValue()));
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Element.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 - 2018 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.view.util.ColSpan;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.util.UUID;
/**
* @author Andres Almiray
*/
public abstract class Element<E extends Element<E>> {
/**
* Fields can be styled using CSS through ID or class hooks.
*/
protected final StringProperty id = new SimpleStringProperty(UUID.randomUUID().toString());
protected final ListProperty<String> styleClass = new SimpleListProperty<>(FXCollections.observableArrayList());
protected final IntegerProperty span = new SimpleIntegerProperty(12);
/**
* Sets the id property of the current field.
*
* @param newValue
* The new value for the id property.
*
* @return Returns the current field to allow for chaining.
*/
public E id(String newValue) {
id.set(newValue);
return (E) this;
}
/**
* Sets the style classes for the current field.
*
* @param newValue
* The new style classes.
*
* @return Returns the current field to allow for chaining.
*/
public E styleClass(String... newValue) {
styleClass.setAll(newValue);
return (E) this;
}
/**
* Sets the amount of columns the field takes up inside the section grid.
*
* @param newValue
* The new number of columns.
*
* @return Returns the current field to allow for chaining.
*/
public E span(int newValue) {
span.setValue(newValue);
return (E) this;
}
/**
* Sets the amount of columns the field takes up inside the section grid.
*
* @param newValue
* The new span fraction.
*
* @return Returns the current field to allow for chaining.
*/
public E span(ColSpan newValue) {
span.setValue(newValue.valueOf());
return (E) this;
}
public int getSpan() {
return span.get();
}
public IntegerProperty spanProperty() {
return span;
}
public String getID() {
return id.get();
}
public StringProperty idProperty() {
return id;
}
public ObservableList<String> getStyleClass() {
return styleClass.get();
}
public ListProperty<String> styleClassProperty() {
return styleClass;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Field.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.event.FieldEvent;
import com.dlsc.formsfx.model.util.BindingMode;
import com.dlsc.formsfx.model.util.TranslationService;
import com.dlsc.formsfx.view.controls.SimpleControl;
import javafx.beans.InvalidationListener;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Labeled;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* This class provides the base implementation for a FormsFX field. It is not
* meant to be used directly, but instead acts as a base for concrete
* implementations.
*
* A field is the smallest unit of the form. It contains only the value and
* relevant information.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public abstract class Field<F extends Field<F>> extends Element<F> implements FormElement {
/**
* The label acts as a description for the field. It is always visible to
* the user and tells them what should be entered into the field.
*
* This property is translatable if a {@link TranslationService} is set on
* the containing form.
*/
protected final StringProperty label = new SimpleStringProperty("");
protected final StringProperty labelKey = new SimpleStringProperty("");
/**
* The tooltip is an extension of the label. It contains additional
* information about the contained data that is only contextually visible.
*
* This property is translatable if a {@link TranslationService} is set on
* the containing form.
*/
protected final StringProperty tooltip = new SimpleStringProperty("");
protected final StringProperty tooltipKey = new SimpleStringProperty("");
/**
* The placeholder is only visible in an empty field. It provides a hint to
* the user about what should be entered into the field.
*
* This property is translatable if a {@link TranslationService} is set on
* the containing form.
*/
protected final StringProperty placeholder = new SimpleStringProperty("");
protected final StringProperty placeholderKey = new SimpleStringProperty("");
/**
* Every field can be marked as {@code required} and {@code editable}. These
* properties can change the field's behaviour.
*/
protected final StringProperty requiredErrorKey = new SimpleStringProperty("");
protected final StringProperty requiredError = new SimpleStringProperty("");
protected final BooleanProperty required = new SimpleBooleanProperty(false);
protected final BooleanProperty editable = new SimpleBooleanProperty(true);
/**
* The field's current state is represented by the value properties, as
* well as by the {@code valid} and {@code changed} flags.
*/
protected final BooleanProperty valid = new SimpleBooleanProperty(true);
protected final BooleanProperty changed = new SimpleBooleanProperty(false);
/**
* Fields can be styled using CSS through ID or class hooks.
*/
protected final StringProperty id = new SimpleStringProperty(UUID.randomUUID().toString());
protected final ListProperty<String> styleClass = new SimpleListProperty<>(FXCollections.observableArrayList());
protected final IntegerProperty span = new SimpleIntegerProperty(12);
/**
* The results of the field's validation is stored in this property. After
* every validation, the results are updated and reflected in this property.
*
* This property is translatable if a {@link TranslationService} is set on
* the containing form.
*/
protected final ListProperty<String> errorMessages = new SimpleListProperty<>(FXCollections.observableArrayList());
protected final ListProperty<String> errorMessageKeys = new SimpleListProperty<>(FXCollections.observableArrayList());
/**
* Additional descriptions for the field's label and value are stored in these properties.
*
* These properties are translatable if a {@link TranslationService} is set on
* the containing form.
*/
private Node labelDescription;
private Node valueDescription;
private final StringProperty labelDescriptionKey = new SimpleStringProperty("");
private final StringProperty valueDescriptionKey = new SimpleStringProperty("");
private static final String LABEL_DESCRIPTION_STYLE_CLASS = "field-label-description";
private static final String VALUE_DESCRIPTION_STYLE_CLASS = "field-value-description";
/**
* The translation service is passed down from the containing section. It
* is used to translate all translatable values of the field.
*/
protected TranslationService translationService;
protected SimpleControl<F> renderer;
protected Supplier<SimpleControl<F>> rendererSupplier;
protected final Map<EventType<FieldEvent>,List<EventHandler<? super FieldEvent>>> eventHandlers = new ConcurrentHashMap<>();
/**
* With the continuous binding mode, values are always directly persisted
* upon any changes.
*/
protected final InvalidationListener bindingModeListener = (observable) -> {
if (validate()) {
persist();
}
};
/**
* Internal constructor for the {@code Field} class. To create new elements,
* see the static factory methods in this class.
*
* @see Field::ofStringType
* @see Field::ofIntegerType
* @see Field::ofDoubleType
* @see Field::ofBooleanType
* @see Field::ofMultiSelectionType
* @see Field::ofSingleSelectionType
*/
protected Field() {
// Whenever one of the translatable elements' keys change, update the
// displayed value based on the new translation.
labelKey.addListener((observable, oldValue, newValue) -> label.setValue(translationService.translate(newValue)));
tooltipKey.addListener((observable, oldValue, newValue) -> tooltip.setValue(translationService.translate(newValue)));
placeholderKey.addListener((observable, oldValue, newValue) -> placeholder.setValue(translationService.translate(newValue)));
labelDescriptionKey.addListener((observable, oldValue, newValue) -> labelDescription = asLabel(translationService.translate(newValue), LABEL_DESCRIPTION_STYLE_CLASS));
valueDescriptionKey.addListener((observable, oldValue, newValue) -> valueDescription = asLabel(translationService.translate(newValue), VALUE_DESCRIPTION_STYLE_CLASS));
requiredErrorKey.addListener((observable, oldValue, newValue) -> validate());
// Whenever the errorMessageKeys change, update the displayed
// label to the new translation. This maps the keys to their translated
// representation.
errorMessageKeys.addListener((observable, oldValue, newValue) -> errorMessages.setAll(errorMessageKeys.stream()
.map(s -> translationService.translate(s))
.collect(Collectors.toList())));
}
/**
* Creates a new {@link PasswordField} with the given default value.
*
* @param defaultValue
* The initial value and persistent value of the field.
*
* @return Returns a new {@link PasswordField}.
*/
public static PasswordField ofPasswordType(String defaultValue) {
return new PasswordField(new SimpleStringProperty(defaultValue), new SimpleStringProperty(defaultValue));
}
/**
* Creates a new {@link PasswordField} with the given property.
*
* @param binding
* The property from the model to be bound with.
*
* @return Returns a new {@link PasswordField}.
*/
public static PasswordField ofPasswordType(StringProperty binding) {
return new PasswordField(new SimpleStringProperty(binding.getValue()), new SimpleStringProperty(binding.getValue())).bind(binding);
}
/**
* Creates a new {@link StringField} with the given default value.
*
* @param defaultValue
* The initial value and persistent value of the field.
*
* @return Returns a new {@link StringField}.
*/
public static StringField ofStringType(String defaultValue) {
return new StringField(new SimpleStringProperty(defaultValue), new SimpleStringProperty(defaultValue));
}
/**
* Creates a new {@link StringField} with the given property.
*
* @param binding
* The property from the model to be bound with.
*
* @return Returns a new {@link StringField}.
*/
public static StringField ofStringType(StringProperty binding) {
return new StringField(new SimpleStringProperty(binding.getValue()), new SimpleStringProperty(binding.getValue())).bind(binding);
}
/**
* Creates a new {@link DoubleField} with the given default value.
*
* @param defaultValue
* The initial value and persistent value of the field.
*
* @return Returns a new {@link DoubleField}.
*/
public static DoubleField ofDoubleType(double defaultValue) {
return new DoubleField(new SimpleDoubleProperty(defaultValue), new SimpleDoubleProperty(defaultValue));
}
/**
* Creates a new {@link DoubleField} with the given property.
*
* @param binding
* The property from the model to be bound with.
*
* @return Returns a new {@link DoubleField}.
*/
public static DoubleField ofDoubleType(DoubleProperty binding) {
return new DoubleField(new SimpleDoubleProperty(binding.getValue()), new SimpleDoubleProperty(binding.getValue())).bind(binding);
}
/**
* Creates a new {@link IntegerField} with the given default value.
*
* @param defaultValue
* The initial value and persistent value of the field.
*
* @return Returns a new {@link IntegerField}.
*/
public static IntegerField ofIntegerType(int defaultValue) {
return new IntegerField(new SimpleIntegerProperty(defaultValue), new SimpleIntegerProperty(defaultValue));
}
/**
* Creates a new {@link IntegerField} with the given property.
*
* @param binding
* The property from the model to be bound with.
*
* @return Returns a new {@link IntegerField}.
*/
public static IntegerField ofIntegerType(IntegerProperty binding) {
return new IntegerField(new SimpleIntegerProperty(binding.getValue()), new SimpleIntegerProperty(binding.getValue())).bind(binding);
}
/**
* Creates a new {@link BooleanField} with the given default value.
*
* @param defaultValue
* The initial value and persistent value of the field.
*
* @return Returns a new {@link BooleanField}.
*/
public static BooleanField ofBooleanType(boolean defaultValue) {
return new BooleanField(new SimpleBooleanProperty(defaultValue), new SimpleBooleanProperty(defaultValue));
}
/**
* Creates a new {@link BooleanField} with the given property.
*
* @param binding
* The property from the model to be bound with.
*
* @return Returns a new {@link BooleanField}.
*/
public static BooleanField ofBooleanType(BooleanProperty binding) {
return new BooleanField(new SimpleBooleanProperty(binding.getValue()), new SimpleBooleanProperty(binding.getValue())).bind(binding);
}
/**
* Creates a new {@link MultiSelectionField} with the given items and a
* pre-defined selection.
*
* @param items
* The list of available items on the field.
* @param selection
* The pre-defined indices of the selected items.
*
* @return Returns a new {@link MultiSelectionField}.
*/
public static <T> MultiSelectionField<T> ofMultiSelectionType(List<T> items, List<Integer> selection) {
return new MultiSelectionField<>(new SimpleListProperty<>(FXCollections.observableArrayList(items)), selection);
}
/**
* Creates a new {@link MultiSelectionField} with the given items and no
* pre-defined selection.
*
* @param items
* The list of available items on the field.
*
* @return Returns a new {@link MultiSelectionField}.
*/
public static <T> MultiSelectionField<T> ofMultiSelectionType(List<T> items) {
return new MultiSelectionField<>(new SimpleListProperty<>(FXCollections.observableArrayList(items)), new ArrayList<>());
}
/**
* Creates a new {@link MultiSelectionField} with the given properties for
* items and selection.
*
* @param itemsBinding
* The items property to be bound with.
*
* @param selectionBinding
* The selection property to be bound with.
*
* @return Returns a new {@link MultiSelectionField}.
*/
public static <T> MultiSelectionField<T> ofMultiSelectionType(ListProperty<T> itemsBinding, ListProperty<T> selectionBinding) {
return new MultiSelectionField<>(new SimpleListProperty<>(itemsBinding.getValue()), new ArrayList<>(selectionBinding.getValue().stream().map(t -> itemsBinding.getValue().indexOf(t)).collect(Collectors.toList()))).bind(itemsBinding, selectionBinding);
}
/**
* Creates a new {@link SingleSelectionField} with the given items and a
* pre-defined selection.
*
* @param items
* The list of available items on the field.
* @param selection
* The pre-defined index of the selected item.
*
* @return Returns a new {@link SingleSelectionField}.
*/
public static <T> SingleSelectionField<T> ofSingleSelectionType(List<T> items, int selection) {
return new SingleSelectionField<>(new SimpleListProperty<>(FXCollections.observableArrayList(items)), selection);
}
/**
* Creates a new {@link SingleSelectionField} with the given items and no
* pre-defined selection.
*
* @param items
* The list of available items on the field.
*
* @return Returns a new {@link SingleSelectionField}.
*/
public static <T> SingleSelectionField<T> ofSingleSelectionType(List<T> items) {
return new SingleSelectionField<>(new SimpleListProperty<>(FXCollections.observableArrayList(items)), -1);
}
/**
* Creates a new {@link SingleSelectionField} with the given properties for
* items and selection.
*
* @param itemsBinding
* The items property to be bound with.
*
* @param selectionBinding
* The selection property to be bound with.
*
* @return Returns a new {@link SingleSelectionField}.
*/
public static <T> SingleSelectionField<T> ofSingleSelectionType(ListProperty<T> itemsBinding, ObjectProperty<T> selectionBinding) {
return new SingleSelectionField<>(new SimpleListProperty<>(itemsBinding.getValue()), itemsBinding.indexOf(selectionBinding.getValue())).bind(itemsBinding, selectionBinding);
}
/**
* Creates a new {@link DateField} with given default value
*
* @param defaultValue The initial value and persistent value of the field.
* @return Returns a new {@link DateField}.
*/
public static DateField ofDate(LocalDate defaultValue) {
return new DateField(new SimpleObjectProperty<>(defaultValue), new SimpleObjectProperty<>(defaultValue));
}
/**
* Creates a new {@link DateField} with given property
*
* @param binding The property from the model to be bound with.
* @return Returns a new {@link DateField}.
*/
public static DateField ofDate(ObjectProperty<LocalDate> binding) {
return new DateField(new SimpleObjectProperty<>(binding.getValue()), new SimpleObjectProperty<>(binding.getValue())).bind(binding);
}
/**
* Sets the required property to for the current field without providing an
* error message.
*
* @param newValue
* The new state of the required property.
*
* @return Returns the current field to allow for chaining.
*/
public F required(boolean newValue) {
required.set(newValue);
validate();
return (F) this;
}
/**
* Sets the required property to true for the current field.
*
* @param errorMessage
* The error message if the field is not filled in.
*
* @return Returns the current field to allow for chaining.
*/
public F required(String errorMessage) {
required.set(true);
if (isI18N()) {
requiredErrorKey.set(errorMessage);
} else {
requiredError.set(errorMessage);
}
validate();
return (F) this;
}
/**
* Sets the editable property of the current field.
*
* @param newValue
* The new value for the editable property.
*
* @return Returns the current field to allow for chaining.
*/
public F editable(boolean newValue) {
editable.set(newValue);
return (F) this;
}
/**
* Sets the label property of the current field.
*
* @param newValue
* The new value for the label property. This can be the label
* itself or a key that is then used for translation.
*
* @see TranslationService
*
* @return Returns the current field to allow for chaining.
*/
public F label(String newValue) {
if (isI18N()) {
labelKey.set(newValue);
} else {
label.set(newValue);
}
return (F) this;
}
/**
* Sets the label description property of the current field.
*
* @param newValue
* The new value for the label description property.
*
*
* @return Returns the current field to allow for chaining.
*/
public F labelDescription(Node newValue) {
labelDescription = newValue;
if (labelDescription != null) {
labelDescription.getStyleClass().add(LABEL_DESCRIPTION_STYLE_CLASS);
}
return (F) this;
}
/**
* Sets the label description property of the current field.
*
* @param newValue
* The new value for the label description property,
* wrapped with a {@code Text}.
*
*
* @return Returns the current field to allow for chaining.
*/
public F labelDescription(String newValue) {
if(isI18N()) {
labelDescriptionKey.set(newValue);
} else if (newValue != null) {
labelDescription = asLabel(newValue, LABEL_DESCRIPTION_STYLE_CLASS);
}
return (F) this;
}
/**
* Sets the value description property of the current field.
*
* @param newValue
* The new value for the field description property.
*
*
* @return Returns the current field to allow for chaining.
*/
public F valueDescription(Node newValue) {
valueDescription = newValue;
if (valueDescription != null) {
valueDescription.getStyleClass().add(VALUE_DESCRIPTION_STYLE_CLASS);
}
return (F) this;
}
/**
* Sets the value description property of the current field.
*
* @param newValue
* The new value for the field description property,
* wrapped with a {@code Text}.
*
*
* @return Returns the current field to allow for chaining.
*/
public F valueDescription(String newValue) {
if(isI18N()) {
valueDescriptionKey.set(newValue);
} else if (newValue != null) {
valueDescription = asLabel(newValue, VALUE_DESCRIPTION_STYLE_CLASS);
}
return (F) this;
}
private Label asLabel(String text, String styleClass) {
Label label = new Label(text);
label.setWrapText(true);
label.getStyleClass().add(styleClass);
return label;
}
/**
* Sets the tooltip property of the current field.
*
* @param newValue
* The new value for the tooltip property. This can be the
* label itself or a key that is then used for translation.
*
* @see TranslationService
*
* @return Returns the current field to allow for chaining.
*/
public F tooltip(String newValue) {
if (isI18N()) {
tooltipKey.set(newValue);
} else {
tooltip.set(newValue);
}
return (F) this;
}
/**
* Sets the placeholder property of the current field.
*
* @param newValue
* The new value for the placeholder property. This can be the
* label itself or a key that is then used for translation.
*
* @see TranslationService
*
* @return Returns the current field to allow for chaining.
*/
public F placeholder(String newValue) {
if (isI18N()) {
placeholderKey.set(newValue);
} else {
placeholder.set(newValue);
}
return (F) this;
}
/**
* Sets the control that renders this field.
*
* @param newValue
* The new control to render the field.
*
* @return Returns the current field to allow for chaining.
*/
public F render(SimpleControl<F> newValue) {
renderer = newValue;
return (F) this;
}
/**
* Sets the control supplier that renders this field.
* The supplier is only called when required, i.e., when the GUI is created.
*
* @param newValue
* The new control supplier to render the field.
*
* @return Returns the current field to allow for chaining.
*/
public F render(Supplier<SimpleControl<F>> newValue) {
rendererSupplier = newValue;
return (F) this;
}
/**
* Activates or deactivates the {@code bindingModeListener} based on the
* given {@code BindingMode}.
*
* @param newValue
* The new binding mode for the current field.
*/
public abstract void setBindingMode(BindingMode newValue);
// abstract void persist();
// abstract void reset();
/**
* This internal method is called by the containing section when a new
* translation has been added to the form.
*
* @param newValue
* The new service to use for translating translatable values.
*/
public void translate(TranslationService newValue) {
translationService = newValue;
if (!isI18N()) {
return;
}
updateElement(label, labelKey);
updateElement(tooltip, tooltipKey);
updateElement(placeholder, placeholderKey);
updateElement(requiredError, requiredErrorKey);
updateElement(labelDescription, labelDescriptionKey);
updateElement(valueDescription, valueDescriptionKey);
// Validation results are handled separately as they use a somewhat
// more complex structure.
validate();
}
/**
* Updates a displayable field property to include translated text.
*
* @param displayProperty
* The property that is displayed to the user.
* @param keyProperty
* The internal property that holds the translation key.
*/
protected void updateElement(StringProperty displayProperty, StringProperty keyProperty) {
// If the key has not yet been set that means that the translation
// service was added for the first time. We can simply set the key
// to the value stored in the display property, the listener will
// then take care of the translation.
if ((keyProperty.get() == null || keyProperty.get().isEmpty()) && !displayProperty.get().isEmpty()) {
keyProperty.setValue(displayProperty.get());
} else if (!keyProperty.get().isEmpty()) {
displayProperty.setValue(translationService.translate(keyProperty.get()));
}
}
/**
* Updates a displayable field property to include translated text.
*
* @param node
* The property that is displayed to the user.
* @param keyProperty
* The internal property that holds the translation key.
*/
void updateElement(Node node, StringProperty keyProperty) {
// If the key has not yet been set that means that the translation
// service was added for the first time. We can simply set the key
// to the value stored in the display property, the listener will
// then take care of the translation.
if (!(node instanceof Labeled)) {
// no automatic update
return;
}
Labeled labeled = (Labeled) node;
if ((keyProperty.get() == null || keyProperty.get().isEmpty()) && !labeled.getText().isEmpty()) {
keyProperty.setValue(labeled.getText());
} else if (!keyProperty.get().isEmpty()) {
labeled.setText(translationService.translate(keyProperty.get()));
}
}
/**
* Validates a user input based on the field's value transformer and its
* validation rules. Also considers the {@code required} flag. This method
* directly updates the {@code valid} property.
*
* @return Returns whether the user input is a valid value or not.
*/
protected abstract boolean validate();
public String getPlaceholder() {
return placeholder.get();
}
public StringProperty placeholderProperty() {
return placeholder;
}
public String getLabel() {
return label.get();
}
public StringProperty labelProperty() {
return label;
}
public String getTooltip() {
return tooltip.get();
}
public StringProperty tooltipProperty() {
return tooltip;
}
public boolean isValid() {
return valid.get();
}
public BooleanProperty validProperty() {
return valid;
}
public boolean hasChanged() {
return changed.get();
}
public BooleanProperty changedProperty() {
return changed;
}
public boolean isRequired() {
return required.get();
}
public BooleanProperty requiredProperty() {
return required;
}
public boolean isEditable() {
return editable.get();
}
public BooleanProperty editableProperty() {
return editable;
}
public boolean isI18N() {
return translationService != null;
}
public SimpleControl<F> getRenderer() {
if (renderer == null) {
renderer = rendererSupplier.get();
}
return renderer;
}
public List<String> getErrorMessages() {
return errorMessages.get();
}
public ListProperty<String> errorMessagesProperty() {
return errorMessages;
}
/**
* Registers an event handler to this field. The handler is called when the
* field receives an {@code Event} of the specified type during the bubbling
* phase of event delivery.
*
* @param eventType the type of the events to receive by the handler
* @param eventHandler the handler to register
*
* @throws NullPointerException if either event type or handler are {@code null}.
*/
public Field addEventHandler(EventType<FieldEvent> eventType, EventHandler<? super FieldEvent> eventHandler) {
if (eventType == null) {
throw new NullPointerException("Argument eventType must not be null");
}
if (eventHandler == null) {
throw new NullPointerException("Argument eventHandler must not be null");
}
this.eventHandlers.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>()).add(eventHandler);
return this;
}
/**
* Unregisters a previously registered event handler from this field. One
* handler might have been registered for different event types, so the
* caller needs to specify the particular event type from which to
* unregister the handler.
*
* @param eventType the event type from which to unregister
* @param eventHandler the handler to unregister
*
* @throws NullPointerException if either event type or handler are {@code null}.
*/
public Field removeEventHandler(EventType<FieldEvent> eventType, EventHandler<? super FieldEvent> eventHandler) {
if (eventType == null) {
throw new NullPointerException("Argument eventType must not be null");
}
if (eventHandler == null) {
throw new NullPointerException("Argument eventHandler must not be null");
}
List<EventHandler<? super FieldEvent>> list = this.eventHandlers.get(eventType);
if (list != null) {
list.remove(eventHandler);
}
return this;
}
protected void fireEvent(FieldEvent event) {
List<EventHandler<? super FieldEvent>> list = this.eventHandlers.get(event.getEventType());
if (list == null) {
return;
}
for (EventHandler<? super FieldEvent> eventHandler : list) {
if (!event.isConsumed()) {
eventHandler.handle(event);
}
}
}
public Node getLabelDescription() {
return labelDescription;
}
public Node getValueDescription() {
return valueDescription;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Form.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.event.FormEvent;
import com.dlsc.formsfx.model.util.BindingMode;
import com.dlsc.formsfx.model.util.TranslationService;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.EventHandler;
import javafx.event.EventType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
/**
* A form is the containing unit for sections and elements and is used to bring
* structure to form data. It also acts as a proxy to some properties of the
* contained data, such as validity or changes.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class Form {
protected final List<Group> groups = new ArrayList<>();
/**
* The title acts as a description for the form.
*
* This property is translatable if a {@link TranslationService} is set.
*/
protected final StringProperty title = new SimpleStringProperty("");
protected final StringProperty titleKey = new SimpleStringProperty("");
/**
* The form acts as a proxy for its contained sections' {@code changed}
* and {@code valid} properties.
*/
protected final BooleanProperty valid = new SimpleBooleanProperty(true);
protected final BooleanProperty changed = new SimpleBooleanProperty(false);
protected final BooleanProperty persistable = new SimpleBooleanProperty(false);
/**
* A form can optionally have a translation service. This service is used to
* translate displayed values into multiple locales. The form registers
* itself as a listener on the translation service to handle locale changes.
*
* @see TranslationService
*/
protected final ObjectProperty<TranslationService> translationService = new SimpleObjectProperty<>();
protected final Runnable localeChangeListener = this::translate;
private final Map<EventType<FormEvent>,List<EventHandler<? super FormEvent>>> eventHandlers = new ConcurrentHashMap<>();
/**
* Internal constructor for the {@code Form} class. To create new
* forms, see the static factory method in this class.
*
* @see Form::of
*
* @param groups
* A varargs list of groups that are contained in this
* form.
*/
private Form(Group... groups) {
Collections.addAll(this.groups, groups);
// If any of the groups are marked as changed, the section is updated
// accordingly.
this.groups.forEach(s -> s.changedProperty().addListener((observable, oldValue, newValue) -> setChangedProperty()));
// If any of the groups are marked as invalid, the section is updated
// accordingly.
this.groups.forEach(s -> s.validProperty().addListener((observable, oldValue, newValue) -> setValidProperty()));
setValidProperty();
setChangedProperty();
setPersistableProperty();
// Whenever the title's key changes, update the displayed value based
// on the new translation.
titleKey.addListener((observable, oldValue, newValue) -> title.setValue(translationService.get().translate(newValue)));
// Whenever the underlying translation service changes, update all
// translation on the form and its contained elements.
translationService.addListener((observable, oldValue, newValue) -> translate());
}
/**
* Creates a new form containing the given sections.
*
* @param sections
* The sections to be included in the form.
*
* @return Returns a new {@code Form}.
*/
public static Form of(Group... sections) {
return new Form(sections);
}
/**
* Sets the title property of the current form.
*
* @param newValue
* The new value for the title property. This can be the title
* itself or a key that is then used for translation.
*
* @see TranslationService
*
* @return Returns the current form to allow for chaining.
*/
public Form title(String newValue) {
if (isI18N()) {
titleKey.set(newValue);
} else {
title.set(newValue);
}
return this;
}
/**
* Sets the translation service property of the current form.
*
* @param newValue
* The new value for the translation service property.
*
* @return Returns the current form to allow for chaining.
*/
public Form i18n(TranslationService newValue) {
if (translationService.get() != null) {
translationService.get().removeListener(localeChangeListener);
}
translationService.setValue(newValue);
translationService.get().addListener(localeChangeListener);
return this;
}
/**
* Changes the way field values are bound to external properties.
*
* @see BindingMode
*
* @param newValue
* The new mode for handling external bindings.
*
* @return Returns the current form to allow for chaining.
*/
public Form binding(BindingMode newValue) {
getFields().forEach(f -> f.setBindingMode(newValue));
return this;
}
/**
* This internal method is used as a callback for when the translation
* service or its locale changes. Also applies the translation to all
* contained sections.
*
* @see Group::translate
*/
protected void translate() {
TranslationService tr = translationService.get();
if (!isI18N()) {
return;
}
if (titleKey.get() == null || titleKey.get().isEmpty()) {
titleKey.setValue(title.get());
} else {
title.setValue(tr.translate(titleKey.get()));
}
groups.forEach(s -> s.translate(tr));
}
/**
* Persists the values for all elements contained in this form's groups.
*
* @see Field::reset
*/
public void persist() {
if (!isPersistable()) {
return;
}
groups.forEach(Group::persist);
fireEvent(FormEvent.formPersistedEvent(this));
}
/**
* Resets the values for all elements contained in this form's groups.
*
* @see Field::reset
*/
public void reset() {
if (!hasChanged()) {
return;
}
groups.forEach(Group::reset);
fireEvent(FormEvent.formResetEvent(this));
}
/**
* Sets this form's {@code changed} property based on its contained
* groups' changed properties.
*/
protected void setChangedProperty() {
changed.setValue(groups.stream().anyMatch(Group::hasChanged));
setPersistableProperty();
}
/**
* Sets this form's {@code valid} property based on its contained groups'
* changed properties.
*/
protected void setValidProperty() {
valid.setValue(groups.stream().allMatch(Group::isValid));
setPersistableProperty();
}
/**
* Sets this form's {@code persistable} property based on its contained
* groups' persistable properties.
*/
protected void setPersistableProperty() {
persistable.setValue(groups.stream().anyMatch(Group::hasChanged) && groups.stream().allMatch(Group::isValid));
}
public List<Group> getGroups() {
return groups;
}
public List<Element> getElements() {
return groups.stream()
.map(Group::getElements)
.flatMap(List::stream)
.collect(Collectors.toList());
}
public List<Field> getFields() {
return groups.stream()
.map(Group::getElements)
.flatMap(List::stream)
.filter(e -> e instanceof Field)
.map(e -> (Field) e)
.collect(Collectors.toList());
}
public boolean hasChanged() {
return changed.get();
}
public BooleanProperty changedProperty() {
return changed;
}
public boolean isValid() {
return valid.get();
}
public BooleanProperty validProperty() {
return valid;
}
public boolean isPersistable() {
return persistable.get();
}
public BooleanProperty persistableProperty() {
return persistable;
}
public String getTitle() {
return title.get();
}
public StringProperty titleProperty() {
return title;
}
public boolean isI18N() {
return translationService.get() != null;
}
/**
* Registers an event handler to this form. The handler is called when the
* form receives an {@code Event} of the specified type during the bubbling
* phase of event delivery.
*
* @param eventType the type of the events to receive by the handler
* @param eventHandler the handler to register
*
* @throws NullPointerException if either event type or handler are {@code null}.
*/
public Form addEventHandler(EventType<FormEvent> eventType, EventHandler<? super FormEvent> eventHandler) {
if (eventType == null) {
throw new NullPointerException("Argument eventType must not be null");
}
if (eventHandler == null) {
throw new NullPointerException("Argument eventHandler must not be null");
}
this.eventHandlers.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>()).add(eventHandler);
return this;
}
/**
* Unregisters a previously registered event handler from this form. One
* handler might have been registered for different event types, so the
* caller needs to specify the particular event type from which to
* unregister the handler.
*
* @param eventType the event type from which to unregister
* @param eventHandler the handler to unregister
*
* @throws NullPointerException if either event type or handler are {@code null}.
*/
public Form removeEventHandler(EventType<FormEvent> eventType, EventHandler<? super FormEvent> eventHandler) {
if (eventType == null) {
throw new NullPointerException("Argument eventType must not be null");
}
if (eventHandler == null) {
throw new NullPointerException("Argument eventHandler must not be null");
}
List<EventHandler<? super FormEvent>> list = this.eventHandlers.get(eventType);
if (list != null) {
list.remove(eventHandler);
}
return this;
}
protected void fireEvent(FormEvent event) {
List<EventHandler<? super FormEvent>> list = this.eventHandlers.get(event.getEventType());
if (list == null) {
return;
}
for (EventHandler<? super FormEvent> eventHandler : list) {
if (!event.isConsumed()) {
eventHandler.handle(event);
}
}
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/FormElement.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 - 2018 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
/**
* @author Andres Almiray
*/
public interface FormElement {
void persist();
void reset();
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Group.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.event.GroupEvent;
import com.dlsc.formsfx.model.util.TranslationService;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.EventHandler;
import javafx.event.EventType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* A group is the intermediate unit in a form. It is used to group form
* elements to a larger unit. It also acts as a proxy to some properties of
* the contained data, such as validity or changes.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class Group {
protected final List<Element> elements = new ArrayList<>();
/**
* The group acts as a proxy for its contained elements' {@code changed}
* and {@code valid} properties.
*/
protected final BooleanProperty valid = new SimpleBooleanProperty(true);
protected final BooleanProperty changed = new SimpleBooleanProperty(false);
/**
* The translation service is passed down from the containing form. It
* is used to translate all translatable values of the field.
*/
protected TranslationService translationService;
private final Map<EventType<GroupEvent>,List<EventHandler<? super GroupEvent>>> eventHandlers = new ConcurrentHashMap<>();
/**
* Internal constructor for the {@code Group} class. To create new
* groups, see the static factory method in this class.
*
* @see Group::of
*
* @param elements
* A varargs list of elements that are contained in this
* group.
*/
protected Group(Element... elements) {
Collections.addAll(this.elements, elements);
// If any of the elements are marked as changed, the group is updated
// accordingly.
this.elements.stream()
.filter(e -> e instanceof Field)
.map(e -> (Field) e)
.forEach(f -> f.changedProperty().addListener((observable, oldValue, newValue) -> setChangedProperty()));
// If any of the elements are marked as invalid, the group is updated
// accordingly.
this.elements.stream()
.filter(e -> e instanceof Field)
.map(e -> (Field) e)
.forEach(f -> f.validProperty().addListener((observable, oldValue, newValue) -> setValidProperty()));
setValidProperty();
setChangedProperty();
}
/**
* Creates a new group containing the given elements.
*
* @param elements
* The elements to be included in the group.
*
* @return Returns a new {@code Group}.
*/
public static Group of(Element... elements) {
return new Group(elements);
}
/**
* This internal method is called by the containing form when a new
* translation has been added to the form. Also applies the translation
* to all contained elements.
*
* @see Field::translate
*
* @param newValue
* The new service to use for translating translatable values.
*/
protected void translate(TranslationService newValue) {
translationService = newValue;
if (!isI18N()) {
return;
}
elements.stream()
.filter(e -> e instanceof Field)
.map(e -> (Field) e)
.forEach(f -> f.translate(translationService));
}
/**
* Persists the values for all contained elements.
* @see Field::persist
*/
public void persist() {
if (!isValid()) {
return;
}
elements.stream()
.filter(e -> e instanceof FormElement)
.map(e -> (FormElement) e)
.forEach(FormElement::persist);
fireEvent(GroupEvent.groupPersistedEvent(this));
}
/**
* Resets the values for all contained elements.
* @see Field::reset
*/
public void reset() {
if (!hasChanged()) {
return;
}
elements.stream()
.filter(e -> e instanceof FormElement)
.map(e -> (FormElement) e)
.forEach(FormElement::reset);
}
/**
* Sets this group's {@code changed} property based on its contained
* elements' changed properties.
*/
private void setChangedProperty() {
changed.setValue(elements.stream()
.filter(e -> e instanceof Field)
.map(e -> (Field) e)
.anyMatch(Field::hasChanged));
}
/**
* Sets this group's {@code valid} property based on its contained elements'
* changed properties.
*/
private void setValidProperty() {
valid.setValue(elements.stream()
.filter(e -> e instanceof Field)
.map(e -> (Field) e)
.allMatch(Field::isValid));
}
public List<Element> getElements() {
return elements;
}
public boolean hasChanged() {
return changed.get();
}
public BooleanProperty changedProperty() {
return changed;
}
public boolean isValid() {
return valid.get();
}
public BooleanProperty validProperty() {
return valid;
}
public boolean isI18N() {
return translationService != null;
}
/**
* Registers an event handler to this group. The handler is called when the
* group receives an {@code Event} of the specified type during the bubbling
* phase of event delivery.
*
* @param eventType the type of the events to receive by the handler
* @param eventHandler the handler to register
*
* @throws NullPointerException if either event type or handler are {@code null}.
*/
public Group addEventHandler(EventType<GroupEvent> eventType, EventHandler<? super GroupEvent> eventHandler) {
if (eventType == null) {
throw new NullPointerException("Argument eventType must not be null");
}
if (eventHandler == null) {
throw new NullPointerException("Argument eventHandler must not be null");
}
this.eventHandlers.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>()).add(eventHandler);
return this;
}
/**
* Unregisters a previously registered event handler from this group. One
* handler might have been registered for different event types, so the
* caller needs to specify the particular event type from which to
* unregister the handler.
*
* @param eventType the event type from which to unregister
* @param eventHandler the handler to unregister
*
* @throws NullPointerException if either event type or handler are {@code null}.
*/
public Group removeEventHandler(EventType<GroupEvent> eventType, EventHandler<? super GroupEvent> eventHandler) {
if (eventType == null) {
throw new NullPointerException("Argument eventType must not be null");
}
if (eventHandler == null) {
throw new NullPointerException("Argument eventHandler must not be null");
}
List<EventHandler<? super GroupEvent>> list = this.eventHandlers.get(eventType);
if (list != null) {
list.remove(eventHandler);
}
return this;
}
protected void fireEvent(GroupEvent event) {
List<EventHandler<? super GroupEvent>> list = this.eventHandlers.get(event.getEventType());
if (list == null) {
return;
}
for (EventHandler<? super GroupEvent> eventHandler : list) {
if (!event.isConsumed()) {
eventHandler.handle(event);
}
}
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/IntegerField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.view.controls.SimpleIntegerControl;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
/**
* This class provides an implementation of a {@link Field} containing a
* {@code integer} value.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class IntegerField extends DataField<IntegerProperty, Integer, IntegerField> {
/**
* The constructor of {@code IntegerField}.
*
* @param valueProperty
* The property that is used to store the current valid value
* of the field.
* @param persistentValueProperty
* The property that is used to store the latest persisted
* value of the field.
*/
protected IntegerField(SimpleIntegerProperty valueProperty, SimpleIntegerProperty persistentValueProperty) {
super(valueProperty, persistentValueProperty);
stringConverter = new AbstractStringConverter<Integer>() {
@Override
public Integer fromString(String string) {
return Integer.parseInt(string);
}
};
rendererSupplier = () -> new SimpleIntegerControl();
userInput.set(stringConverter.toString(value.getValue()));
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/MultiSelectionField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.event.FieldEvent;
import com.dlsc.formsfx.model.util.BindingMode;
import com.dlsc.formsfx.model.validators.ValidationResult;
import com.dlsc.formsfx.model.validators.Validator;
import com.dlsc.formsfx.view.controls.SimpleListViewControl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
/**
* This class provides an implementation of a {@link MultiSelectionField}
* allowing for multi-selection.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class MultiSelectionField<V> extends SelectionField<V, MultiSelectionField<V>> {
/**
* A {@code MultiSelectionField} can have multiple items selected. These
* items are stored in a {@code ListProperty}.
*/
protected final ListProperty<V> persistentSelection = new SimpleListProperty<>(FXCollections.observableArrayList());
protected final ListProperty<V> selection = new SimpleListProperty<>(FXCollections.observableArrayList());
/**
* Every field contains a list of validators. The validators are limited to
* the ones that correspond to the field's type.
*/
protected final List<Validator<ObservableList<V>>> validators = new ArrayList<>();
/**
* The constructor of {@code MultiSelectionField}.
*
* @param items
* The property that is used to store the items of the field.
* @param selection
* The list of indices of items that are to be selected.
*/
protected MultiSelectionField(ListProperty<V> items, List<Integer> selection) {
super(items);
// Add items to the selection, based on their indices. This also
// determines the persistent selection.
selection.forEach(i -> {
if (i < this.items.size() && i >= 0) {
this.selection.add(this.items.get(i));
}
});
persistentSelection.addAll(this.selection.getValue());
// The changed property is a binding that compares the persistent
// selection with the current selection. This means that a field is
// marked as changed until Field::persist or Field::reset are called
// or the selection is back to the persistent selection.
changed.bind(Bindings.createBooleanBinding(() -> !persistentSelection.equals(this.selection), this.selection, persistentSelection));
// Changes to the user input are reflected in the value only if the new
// user input is valid.
this.selection.addListener((observable, oldValue, newValue) -> validate());
// Clear the current selection and persistent selection whenever new
// items are added. The selection is built back up if it is passed along
// with the new list of items.
items.addListener((observable, oldValue, newValue) -> {
this.selection.clear();
persistentSelection.clear();
});
rendererSupplier = () -> new SimpleListViewControl<>();
}
/**
* Updates the list of available items to a new list, along with a
* pre-defined selection.
*
* @param newValue
* The new list of items.
* @param newSelection
* The new pre-defined selection.
*
* @return Returns the current field to allow for chaining.
*/
public MultiSelectionField<V> items(List<V> newValue, List<Integer> newSelection) {
items.setAll(newValue);
newSelection.forEach(i -> selection.add(items.get(i)));
persistentSelection.setAll(selection.getValue());
return this;
}
/**
* Updates the list of available items to a new list, without a
* pre-defined selection.
*
* @param newValue
* The new list of items.
*
* @return Returns the current field to allow for chaining.
*/
public MultiSelectionField<V> items(List<V> newValue) {
return this.items(newValue, new ArrayList<>());
}
/**
* Sets the list of validators for the current field. This overrides all
* validators that have previously been added.
*
* @param newValue
* The validators that are to be used for validating this
* field.
*
* @return Returns the current field to allow for chaining.
*/
@SafeVarargs
public final MultiSelectionField<V> validate(Validator<ObservableList<V>>... newValue) {
validators.clear();
Collections.addAll(validators, newValue);
validate();
return this;
}
/**
* Adds the element at the given index to the current selection.
*
* @param index
* The index of the element to be selected.
*
* @return Returns the current field to allow for chaining.
*/
public MultiSelectionField<V> select(int index) {
if (index < items.size() && index > -1 && !selection.contains(items.get(index))) {
selection.add(items.get(index));
}
return this;
}
/**
* Removes the element at the given index from the current selection.
*
* @param index
* The index of the element to be removed.
*
* @return Returns the current field to allow for chaining.
*/
public MultiSelectionField<V> deselect(int index) {
if (index < items.size() && selection.contains(items.get(index))) {
selection.remove(items.get(index));
}
return this;
}
/**
* Binds the given items and selection property with the corresponding
* elements.
*
* @param itemsBinding
* The items property to be bound with.
*
* @param selectionBinding
* The selection property to be bound with.
*
* @return Returns the current field to allow for chaining.
*/
public MultiSelectionField<V> bind(ListProperty<V> itemsBinding, ListProperty<V> selectionBinding) {
items.bindBidirectional(itemsBinding);
selection.bindBidirectional(selectionBinding);
return this;
}
/**
* Unbinds the given items and selection property with the corresponding
* elements.
*
* @param itemsBinding
* The items property to be unbound with.
*
* @param selectionBinding
* The selection property to be unbound with.
*
* @return Returns the current field to allow for chaining.
*/
public MultiSelectionField<V> unbind(ListProperty<V> itemsBinding, ListProperty<V> selectionBinding) {
items.unbindBidirectional(itemsBinding);
selection.unbindBidirectional(selectionBinding);
return this;
}
/**
* {@inheritDoc}
*/
public void setBindingMode(BindingMode newValue) {
if (BindingMode.CONTINUOUS.equals(newValue)) {
selection.addListener(bindingModeListener);
} else {
selection.removeListener(bindingModeListener);
}
}
/**
* Stores the field's current selection in its persistent selection. This
* stores the user's changes in the model.
*/
public void persist() {
if (!isValid()) {
return;
}
persistentSelection.setAll(selection.getValue());
fireEvent(FieldEvent.fieldPersistedEvent(this));
}
/**
* Sets the field's current selection to its persistent selection, thus
* resetting any changes made by the user.
*/
public void reset() {
if (!hasChanged()) {
return;
}
selection.setAll(persistentSelection.getValue());
fireEvent(FieldEvent.fieldResetEvent(this));
}
/**
* {@inheritDoc}
*/
protected boolean validateRequired() {
return !isRequired() || (isRequired() && selection.size() > 0);
}
/**
* Validates a user input based on the field's selection and its validation
* rules. Also considers the {@code required} flag. This method directly
* updates the {@code valid} property.
*
* @return Returns whether the user selection is a valid value or not.
*/
public boolean validate() {
// Check all validation rules and collect any error messages.
List<String> errorMessages = validators.stream()
.map(v -> v.validate(selection.getValue()))
.filter(r -> !r.getResult())
.map(ValidationResult::getErrorMessage)
.collect(Collectors.toList());
return super.validate(errorMessages);
}
public ObservableList<V> getSelection() {
return selection.get();
}
public ListProperty<V> selectionProperty() {
return selection;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/NodeElement.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 - 2018 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import javafx.scene.Node;
/**
* @author Andres Almiray
*/
public class NodeElement<N extends Node> extends Element {
protected N node;
public static <T extends Node> NodeElement<T> of(T node) {
return new NodeElement(node);
}
protected NodeElement(N node) {
if (node == null) {
throw new NullPointerException("Node argument must not be null");
}
this.node = node;
}
public N getNode() {
return node;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/PasswordField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.view.controls.SimplePasswordControl;
import com.dlsc.formsfx.view.controls.SimpleTextControl;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* This class provides an implementation of a {@link Field} containing a
* {@code string} value intended for passwords.
*
* @author Andres Almiray
*/
public class PasswordField extends DataField<StringProperty, String, PasswordField> {
/**
* The constructor of {@code PasswordField}.
*
* @param valueProperty
* The property that is used to store the current valid value
* of the field.
* @param persistentValueProperty
* The property that is used to store the latest persisted
* value of the field.
*/
protected PasswordField(SimpleStringProperty valueProperty, SimpleStringProperty persistentValueProperty) {
super(valueProperty, persistentValueProperty);
stringConverter = new AbstractStringConverter<String>() {
@Override
public String fromString(String string) {
return string;
}
};
rendererSupplier = () -> new SimplePasswordControl();
userInput.set(stringConverter.toString(value.getValue()));
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Section.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.util.TranslationService;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* A section is a kind of group with more options. It can have a title and can
* be collapsed by the user. Sections represent a more semantically heavy
* grouping of elements, compared to groups.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class Section extends Group {
/**
* The title acts as a description for the group. It is always visible to
* the user and tells them how the contained elements are grouped.
*
* This property is translatable if a {@link TranslationService} is set on
* the containing form.
*/
protected final StringProperty titleKey = new SimpleStringProperty("");
protected final StringProperty title = new SimpleStringProperty("");
/**
* A group can optionally be collapsed.
*/
protected final BooleanProperty collapsed = new SimpleBooleanProperty(false);
/**
* Section is collapsible by default
*/
protected final BooleanProperty collapsible = new SimpleBooleanProperty(true);
/**
* {@inheritDoc}
*/
private Section(Element... elements) {
super(elements);
// Whenever the title's key changes, update the displayed value based
// on the new translation.
titleKey.addListener((observable, oldValue, newValue) -> title.setValue(translationService.translate(newValue)));
}
/**
* Creates a new section containing the given elements.
*
* @param elements
* The elements to be included in the section.
*
* @return Returns a new {@code Section}.
*/
public static Section of(Element... elements) {
return new Section(elements);
}
/**
* Sets the title property of the current group.
*
* @param newValue
* The new value for the title property. This can be the title
* itself or a key that is then used for translation.
*
* @see TranslationService
*
* @return Returns the current group to allow for chaining.
*/
public Section title(String newValue) {
if (isI18N()) {
titleKey.set(newValue);
} else {
title.set(newValue);
}
return this;
}
/**
* {@inheritDoc}
*/
protected void translate(TranslationService newValue) {
translationService = newValue;
if (!isI18N()) {
return;
}
if (titleKey.get() == null || titleKey.get().isEmpty()) {
titleKey.setValue(title.get());
} else {
title.setValue(translationService.translate(titleKey.get()));
}
elements.stream()
.filter(e -> e instanceof Field)
.map(e -> (Field) e)
.forEach(f -> f.translate(translationService));
}
/**
* Changes the collapsed state on a section.
*
* @param newValue
* The new value for the collapsed state.
*/
public Section collapse(boolean newValue) {
collapsed.setValue(newValue);
return this;
}
public BooleanProperty collapsedProperty() {
return collapsed;
}
public boolean isCollapsed() {
return collapsed.get();
}
public String getTitle() {
return title.get();
}
public StringProperty titleProperty() {
return title;
}
/**
* Changes the collapsible state on a section.
*
* @param newValue
* The new value for the collapsible state.
*/
public Section collapsible(boolean newValue) {
this.collapsible.set(newValue);
return this;
}
public boolean isCollapsible() {
return collapsible.get();
}
public BooleanProperty collapsibleProperty() {
return collapsible;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/SelectionField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import javafx.beans.property.ListProperty;
import javafx.collections.ObservableList;
import java.util.List;
/**
* {@code SelectionField} holds a list of values. Users can select one or more
* of these values, depending on the concrete type of the field.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public abstract class SelectionField<V, F extends SelectionField<V, F>> extends Field<F> {
/**
* Stores a typed list of available items on this field.
*/
protected final ListProperty<V> items;
/**
* Internal constructor for the {@code SelectionField} class. To create new
* elements, see the static factory methods in {@code Field}.
*
* @see Field::ofMultiSelectionType
* @see Field::ofSingleSelectionType
*
* @param items
* The list of available items on the field.
*/
protected SelectionField(ListProperty<V> items) {
this.items = items;
}
/**
* Validates that the new field input matches the required condition.
*
* @return Returns whether the input matches the required condition.
*/
protected abstract boolean validateRequired();
/**
* Validates a user input based on the field's selection and its validation
* rules. Also considers the {@code required} flag. This method directly
* updates the {@code valid} property.
*
* This method should not be called directly but instead only be used in
* concrete subclasses.
*
* @param errorMessages
* A list of error messages based on the field's validators.
*
* @return Returns whether the user selection is a valid value or not.
*/
protected boolean validate(List<String> errorMessages) {
if (!validateRequired()) {
if (isI18N() && requiredErrorKey.get() != null) {
this.errorMessageKeys.setAll(requiredErrorKey.get());
} else if (requiredError.get() != null) {
this.errorMessages.setAll(requiredError.get());
}
valid.set(false);
return false;
}
// Update the validation results with the current results. Listeners
// will handle the translation aspect.
if (isI18N()) {
errorMessageKeys.setAll(errorMessages);
} else {
this.errorMessages.setAll(errorMessages);
}
if (errorMessages.size() > 0) {
valid.set(false);
return false;
}
// If, and only if all above conditions have succeeded, the user input
// is considered valid.
valid.set(true);
return true;
}
public ObservableList getItems() {
return items.get();
}
public ListProperty<V> itemsProperty() {
return items;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/SingleSelectionField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.model.event.FieldEvent;
import com.dlsc.formsfx.model.util.BindingMode;
import com.dlsc.formsfx.model.validators.ValidationResult;
import com.dlsc.formsfx.model.validators.Validator;
import com.dlsc.formsfx.view.controls.SimpleComboBoxControl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ListProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
/**
* This class provides an implementation of a {@link SelectionField} allowing
* only for single selection.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class SingleSelectionField<V> extends SelectionField<V, SingleSelectionField<V>> {
/**
* A {@code SingleSelectionField} can only ever have one item selected.
* This item is stored in an {@code ObjectProperty}.
*/
protected final ObjectProperty<V> persistentSelection = new SimpleObjectProperty<>();
protected final ObjectProperty<V> selection = new SimpleObjectProperty<>();
/**
* Every field contains a list of validators. The validators are limited to
* the ones that correspond to the field's type.
*/
protected final List<Validator<V>> validators = new ArrayList<>();
/**
* The constructor of {@code SingleSelectionField}.
*
* @param items
* The property that is used to store the items of the field.
* @param selection
* The index of the item that is to be selected.
*/
protected SingleSelectionField(ListProperty<V> items, int selection) {
super(items);
// Sets the initial selection, based on an index. This also determines
// the persistent selection.
if (selection < items.size() && selection >= 0) {
this.selection.set(this.items.get(selection));
persistentSelection.setValue(this.selection.getValue());
}
// The changed property is a binding that compares the persistent
// selection with the current selection. This means that a field is
// marked as changed until Field::persist or Field::reset are called
// or the selection is back to the persistent selection.
changed.bind(Bindings.createBooleanBinding(() -> persistentSelection.get() == null ? this.selection.get() != null : !persistentSelection.get().equals(this.selection.get()), this.selection, persistentSelection));
// Changes to the user input are reflected in the value only if the new
// user input is valid.
this.selection.addListener((observable, oldValue, newValue) -> validate());
// Clear the current selection and persistent selection whenever new
// items are added. The selection is built back up if it is passed along
// with the new list of items.
items.addListener((observable, oldValue, newValue) -> {
this.selection.setValue(null);
persistentSelection.setValue(null);
});
rendererSupplier = () -> new SimpleComboBoxControl<>();
}
/**
* Updates the list of available items to a new list, along with a
* pre-defined selection.
*
* @param newValue
* The new list of items.
* @param newSelection
* The new pre-defined selection.
*
* @return Returns the current field to allow for chaining.
*/
public SingleSelectionField<V> items(List<V> newValue, int newSelection) {
items.setAll(newValue);
if (newSelection != -1) {
this.selection.setValue(items.get(newSelection));
this.persistentSelection.setValue(this.selection.getValue());
}
return this;
}
/**
* Updates the list of available items to a new list, without a
* pre-defined selection.
*
* @param newValue
* The new list of items.
*
* @return Returns the current field to allow for chaining.
*/
public SingleSelectionField<V> items(List<V> newValue) {
return this.items(newValue, -1);
}
/**
* Sets the list of validators for the current field. This overrides all
* validators that have previously been added.
*
* @param newValue
* The validators that are to be used for validating this
* field.
*
* @return Returns the current field to allow for chaining.
*/
@SafeVarargs
public final SingleSelectionField<V> validate(Validator<V>... newValue) {
validators.clear();
Collections.addAll(validators, newValue);
validate();
return this;
}
/**
* Sets the selection to the element at the given index.
*
* @param index
* The index of the element to be selected.
*
* @return Returns the current field to allow for chaining.
*/
public SingleSelectionField<V> select(int index) {
if (index == -1) {
selection.setValue(null);
} else if (index < items.size() && index > -1 && (selection.get() == null || (selection.get() != null && !selection.get().equals(items.get(index))))) {
selection.setValue(items.get(index));
}
return this;
}
/**
* Removes the selection on the current field.
*
* @return Returns the current field to allow for chaining.
*/
public SingleSelectionField<V> deselect() {
if (selection.get() != null) {
selection.setValue(null);
}
return this;
}
/**
* Binds the given items and selection property with the corresponding
* elements.
*
* @param itemsBinding
* The items property to be bound with.
*
* @param selectionBinding
* The selection property to be bound with.
*
* @return Returns the current field to allow for chaining.
*/
public SingleSelectionField<V> bind(ListProperty<V> itemsBinding, ObjectProperty<V> selectionBinding) {
items.bindBidirectional(itemsBinding);
selection.bindBidirectional(selectionBinding);
return this;
}
/**
* Unbinds the given items and selection property with the corresponding
* elements.
*
* @param itemsBinding
* The items property to be unbound with.
*
* @param selectionBinding
* The selection property to be unbound with.
*
* @return Returns the current field to allow for chaining.
*/
public SingleSelectionField<V> unbind(ListProperty<V> itemsBinding, ObjectProperty<V> selectionBinding) {
items.unbindBidirectional(itemsBinding);
selection.unbindBidirectional(selectionBinding);
return this;
}
/**
* {@inheritDoc}
*/
public void setBindingMode(BindingMode newValue) {
if (BindingMode.CONTINUOUS.equals(newValue)) {
selection.addListener(bindingModeListener);
} else {
selection.removeListener(bindingModeListener);
}
}
/**
* Stores the field's current value in its persistent value. This stores
* the user's changes in the model.
*/
public void persist() {
if (!isValid()) {
return;
}
persistentSelection.setValue(selection.getValue());
fireEvent(FieldEvent.fieldPersistedEvent(this));
}
/**
* Sets the field's current value to its persistent value, thus resetting
* any changes made by the user.
*/
public void reset() {
if (!hasChanged()) {
return;
}
selection.setValue(persistentSelection.getValue());
fireEvent(FieldEvent.fieldResetEvent(this));
}
/**
* {@inheritDoc}
*/
protected boolean validateRequired() {
return !isRequired() || (isRequired() && selection.get() != null);
}
/**
* Validates a user input based on the field's selection and its validation
* rules. Also considers the {@code required} flag. This method directly
* updates the {@code valid} property.
*
* @return Returns whether the user selection is a valid value or not.
*/
public boolean validate() {
// Check all validation rules and collect any error messages.
List<String> errorMessages = validators.stream()
.map(v -> v.validate(selection.getValue()))
.filter(r -> !r.getResult())
.map(ValidationResult::getErrorMessage)
.collect(Collectors.toList());
return super.validate(errorMessages);
}
public V getSelection() {
return selection.get();
}
public ObjectProperty<V> selectionProperty() {
return selection;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/StringField.java
================================================
package com.dlsc.formsfx.model.structure;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import com.dlsc.formsfx.view.controls.SimpleTextControl;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
* This class provides an implementation of a {@link Field} containing a
* {@code string} value.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class StringField extends DataField<StringProperty, String, StringField> {
protected final BooleanProperty multiline = new SimpleBooleanProperty(false);
/**
* The constructor of {@code StringField}.
*
* @param valueProperty
* The property that is used to store the current valid value
* of the field.
* @param persistentValueProperty
* The property that is used to store the latest persisted
* value of the field.
*/
protected StringField(SimpleStringProperty valueProperty, SimpleStringProperty persistentValueProperty) {
super(valueProperty, persistentValueProperty);
stringConverter = new AbstractStringConverter<String>() {
@Override
public String fromString(String string) {
return string;
}
};
rendererSupplier = () -> new SimpleTextControl();
userInput.set(stringConverter.toString(value.getValue()));
}
/**
* Sets whether the field is considered to be multiline or not.
*
* @param newValue
* The new value for the multiline property.
*
* @return Returns the current field to allow for chaining.
*/
public StringField multiline(boolean newValue) {
multiline.setValue(newValue);
return this;
}
public boolean isMultiline() {
return multiline.get();
}
public BooleanProperty multilineProperty() {
return multiline;
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/util/BindingMode.java
================================================
package com.dlsc.formsfx.model.util;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
/**
* Contains constants for the different ways to handle value bindings.
* {@code CONTINUOUS} persists field values upon any change, while
* {@code PERSISTENT} only persists values when explicitly requested.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public enum BindingMode {
CONTINUOUS,
PERSISTENT
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/util/ResourceBundleService.java
================================================
package com.dlsc.formsfx.model.util;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import java.util.ResourceBundle;
/**
* The ResourceBundleService is a concrete implementation of a
* {@link TranslationService} and uses ResourceBundles to perform translations.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class ResourceBundleService extends TranslationService {
private ResourceBundle rb;
public ResourceBundleService(ResourceBundle rb) {
this.rb = rb;
}
/**
* Change the resource bundle to use for this service. Notifies all
* listeners of the locale change.
*
* @param newValue
* The new resource bundle to use for translations.
*/
public void changeLocale(ResourceBundle newValue) {
if (newValue.equals(rb)) {
return;
}
rb = newValue;
notifyListeners();
}
/**
* {@inheritDoc}
*/
@Override
public String translate(String key) {
return rb.getString(key);
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/util/TranslationService.java
================================================
package com.dlsc.formsfx.model.util;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import java.util.ArrayList;
import java.util.List;
/**
* A general purpose translation service that is used to translate values into
* multiple locales based on keys. A concrete sample implementation is provided
* in the {@link ResourceBundleService}.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public abstract class TranslationService {
private List<Runnable> listeners = new ArrayList<>();
/**
* Looks up a key in the translation service and returns the translate string.
*
* @param key
* The key to use for the lookup.
*
* @return The translated string.
*/
public abstract String translate(String key);
public void addListener(Runnable listener) {
listeners.add(listener);
}
public void removeListener(Runnable listener) {
listeners.remove(listener);
}
/**
* Notifies all listeners of a locale change. Concrete implementations must
* call this method after every locale change.
*/
protected void notifyListeners() {
listeners.forEach(Runnable::run);
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/util/ValueTransformer.java
================================================
package com.dlsc.formsfx.model.util;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
/**
* A value transformer takes a string as an input and returns a parsed type.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
* @deprecated Use {@code StringConverter} instead.
* @see javafx.util.StringConverter
*/
@Deprecated
public interface ValueTransformer<T> {
T transform(String input);
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/CustomValidator.java
================================================
package com.dlsc.formsfx.model.validators;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
import java.util.function.Predicate;
/**
* A custom validator implementation of the root validator. This validator
* takes a generic object as an input parameter and allows users to perform
* any kind of validation.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class CustomValidator<T> extends RootValidator<T> {
private Predicate<T> callback;
protected CustomValidator(Predicate<T> callback, String errorMessage) {
super(errorMessage);
this.callback = callback;
}
public static <E> CustomValidator<E> forPredicate(Predicate<E> callback, String errorMessage) {
return new CustomValidator<>(callback, errorMessage);
}
/**
* {@inheritDoc}
*/
@Override
public ValidationResult validate(T input) {
return createResult(callback.test(input));
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/DoubleRangeValidator.java
================================================
package com.dlsc.formsfx.model.validators;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
/**
* A DoubleRangeValidator checks if a double value is between a minimum and a
* maximum value.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class DoubleRangeValidator extends CustomValidator<Double> {
private DoubleRangeValidator(double min, double max, String errorMessage) {
super(input -> input >= min && input <= max, errorMessage);
}
/**
* Creates a DoubleRangeValidator with given lower and upper bounds.
*
* @param min
* The lower bound for the validation.
* @param max
* The upper bound for the validation.
* @param errorMessage
* The error message that is returned if the validation fails.
*
* @throws IllegalArgumentException
* Thrown if the maximum is not larger than or equal to the
* minimum.
*
* @return Returns a new DoubleRangeValidator.
*/
public static DoubleRangeValidator between(double min, double max, String errorMessage) {
if (min > max) {
throw new IllegalArgumentException("Minimum must not be larger than maximum.");
}
return new DoubleRangeValidator(min, max, errorMessage);
}
/**
* Creates a DoubleRangeValidator with a given lower bound.
*
* @param min
* The lower bound for the validation.
* @param errorMessage
* The error message that is returned if the validation fails.
*
* @return Returns a new DoubleRangeValidator.
*/
public static DoubleRangeValidator atLeast(double min, String errorMessage) {
return new DoubleRangeValidator(min, Double.MAX_VALUE, errorMessage);
}
/**
* Creates a DoubleRangeValidator with a given upper bound.
*
* @param max
* The upper bound for the validation.
* @param errorMessage
* The error message that is returned if the validation fails.
*
* @return Returns a new DoubleRangeValidator.
*/
public static DoubleRangeValidator upTo(double max, String errorMessage) {
return new DoubleRangeValidator(Double.MIN_VALUE, max, errorMessage);
}
/**
* Creates a DoubleRangeValidator with a given lower and upper bound, which
* are equal.
*
* @param value
* The lower and upper bound for the validation.
* @param errorMessage
* The error message that is returned if the validation fails.
*
* @return Returns a new DoubleRangeValidator.
*/
public static DoubleRangeValidator exactly(double value, String errorMessage) {
return new DoubleRangeValidator(value, value, errorMessage);
}
}
================================================
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/IntegerRangeValidator.java
================================================
package com.dlsc.formsfx.model.validators;
/*-
* ========================LICENSE_START=================================
* FormsFX
* %%
* Copyright (C) 2017 DLSC Software & Consulting
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =========================LICENSE_END==================================
*/
/**
* A IntegerRangeValidator checks if an integer value is between a minimum and a
* maximum value.
*
* @author Sacha Schmid
* @author Rinesch Murugathas
*/
public class IntegerRangeValidator extends CustomValidator<Integer> {
private IntegerRangeValidator(int min, int max, String errorMessage) {
super(input -> input >= min && input <= max, errorMessage);
}
/**
* Creates an IntegerRangeValidator with given lower and upper bounds.
*
* @param min
* The lower bound for the validation.
* @param max
* The upper bound for the validation.
* @param errorMessage
* The error message that is returned if the validation fails.
*
* @throws IllegalArgumentException
* Thrown if the maximum is not larger than or equal to the
* minimum.
*
* @return Returns a new IntegerRangeValidator.
*/
public static IntegerRangeValidator between(int min, int max, String errorMessage) {
if (min > max) {
throw new IllegalArgumentException("Minimum must not be larger than maximum.");
}
return new IntegerRangeValidator(min, max, errorMessage);
}
/**
* Creates an IntegerRangeValidator with a given lower bound.
*
* @param min
* The lower bound for the validation.
* @param errorMessage
* The error message that is returned if the validation fails.
*
* @return Returns a new IntegerRangeValidator.
*/
public static IntegerRangeValidator atLeast(int min, String errorMessage) {
return new IntegerRangeValidator(min, Integer.MAX_VALUE, errorMessage);
}
/**
* Creates an IntegerRangeValidator with a given upper bound.
*
* @param max
* The upper bound for the validation.
* @param errorMessage
* The error message that is returned if the validation fails.
*
* @return Returns a new IntegerRangeValidator.
*/
public static IntegerRangeValidator upTo(int max, String errorMessage) {
return new IntegerRangeValidator(Integer.MIN_VALUE, max, errorMessage);
}
/**
* Creates a IntegerRangeValidator with a giv
gitextract_xva4uep3/ ├── .github/ │ └── workflows/ │ ├── build.yml │ └── release.yml ├── .gitignore ├── .mvn/ │ └── wrapper/ │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── CHANGELOG.md ├── LICENSE ├── README.md ├── docs/ │ ├── Project Report.pages/ │ │ └── Metadata/ │ │ ├── BuildVersionHistory.plist │ │ ├── DocumentIdentifier │ │ └── Properties.plist │ ├── architecture.xml │ ├── controls.sketch │ ├── grid.sketch │ └── work.sketch ├── formsfx-core/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ ├── license/ │ │ ├── apache20/ │ │ │ ├── header.txt │ │ │ └── license.txt │ │ └── licenses.properties │ ├── main/ │ │ ├── java/ │ │ │ ├── com/ │ │ │ │ └── dlsc/ │ │ │ │ └── formsfx/ │ │ │ │ ├── model/ │ │ │ │ │ ├── event/ │ │ │ │ │ │ ├── FieldEvent.java │ │ │ │ │ │ ├── FormEvent.java │ │ │ │ │ │ └── GroupEvent.java │ │ │ │ │ ├── structure/ │ │ │ │ │ │ ├── BooleanField.java │ │ │ │ │ │ ├── DataField.java │ │ │ │ │ │ ├── DateField.java │ │ │ │ │ │ ├── DoubleField.java │ │ │ │ │ │ ├── Element.java │ │ │ │ │ │ ├── Field.java │ │ │ │ │ │ ├── Form.java │ │ │ │ │ │ ├── FormElement.java │ │ │ │ │ │ ├── Group.java │ │ │ │ │ │ ├── IntegerField.java │ │ │ │ │ │ ├── MultiSelectionField.java │ │ │ │ │ │ ├── NodeElement.java │ │ │ │ │ │ ├── PasswordField.java │ │ │ │ │ │ ├── Section.java │ │ │ │ │ │ ├── SelectionField.java │ │ │ │ │ │ ├── SingleSelectionField.java │ │ │ │ │ │ └── StringField.java │ │ │ │ │ ├── util/ │ │ │ │ │ │ ├── BindingMode.java │ │ │ │ │ │ ├── ResourceBundleService.java │ │ │ │ │ │ ├── TranslationService.java │ │ │ │ │ │ └── ValueTransformer.java │ │ │ │ │ └── validators/ │ │ │ │ │ ├── CustomValidator.java │ │ │ │ │ ├── DoubleRangeValidator.java │ │ │ │ │ ├── IntegerRangeValidator.java │ │ │ │ │ ├── RegexValidator.java │ │ │ │ │ ├── RootValidator.java │ │ │ │ │ ├── SelectionLengthValidator.java │ │ │ │ │ ├── StringLengthValidator.java │ │ │ │ │ ├── ValidationResult.java │ │ │ │ │ └── Validator.java │ │ │ │ └── view/ │ │ │ │ ├── controls/ │ │ │ │ │ ├── SimpleBooleanControl.java │ │ │ │ │ ├── SimpleCheckBoxControl.java │ │ │ │ │ ├── SimpleComboBoxControl.java │ │ │ │ │ ├── SimpleControl.java │ │ │ │ │ ├── SimpleDateControl.java │ │ │ │ │ ├── SimpleDoubleControl.java │ │ │ │ │ ├── SimpleIntegerControl.java │ │ │ │ │ ├── SimpleListViewControl.java │ │ │ │ │ ├── SimpleNumberControl.java │ │ │ │ │ ├── SimplePasswordControl.java │ │ │ │ │ ├── SimpleRadioButtonControl.java │ │ │ │ │ └── SimpleTextControl.java │ │ │ │ ├── renderer/ │ │ │ │ │ ├── FormRenderer.java │ │ │ │ │ ├── GroupRenderer.java │ │ │ │ │ ├── GroupRendererBase.java │ │ │ │ │ └── SectionRenderer.java │ │ │ │ └── util/ │ │ │ │ ├── ColSpan.java │ │ │ │ └── ViewMixin.java │ │ │ └── module-info.java │ │ └── resources/ │ │ └── com/ │ │ └── dlsc/ │ │ └── formsfx/ │ │ └── view/ │ │ └── renderer/ │ │ └── style.css │ └── test/ │ ├── java/ │ │ └── com/ │ │ └── dlsc/ │ │ └── formsfx/ │ │ ├── model/ │ │ │ ├── structure/ │ │ │ │ ├── FieldTest.java │ │ │ │ ├── FormTest.java │ │ │ │ └── SectionTest.java │ │ │ ├── util/ │ │ │ │ └── ResourceBundleServiceTest.java │ │ │ └── validators/ │ │ │ ├── CustomValidatorTest.java │ │ │ ├── DoubleRangeValidatorTest.java │ │ │ ├── IntegerRangeValidatorTest.java │ │ │ ├── RegexValidatorTest.java │ │ │ ├── SelectionLengthValidatorTest.java │ │ │ └── StringLengthValidatorTest.java │ │ └── view/ │ │ ├── controls/ │ │ │ └── SimpleControlTest.java │ │ └── renderer/ │ │ └── RendererTest.java │ └── resources/ │ ├── testbundle_de_CH.properties │ └── testbundle_en_UK.properties ├── formsfx-demo/ │ ├── .gitignore │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ ├── com/ │ │ │ └── dlsc/ │ │ │ └── formsfx/ │ │ │ └── demo/ │ │ │ ├── Demo.java │ │ │ ├── model/ │ │ │ │ ├── Country.java │ │ │ │ └── DemoModel.java │ │ │ └── view/ │ │ │ └── RootPane.java │ │ └── module-info.java │ └── resources/ │ ├── demo-locale_de_CH.properties │ ├── demo-locale_en_UK.properties │ └── style.css ├── jreleaser.yml ├── mvnw ├── mvnw.cmd └── pom.xml
SYMBOL INDEX (508 symbols across 67 files)
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/event/FieldEvent.java
class FieldEvent (line 32) | public final class FieldEvent extends Event {
method fieldPersistedEvent (line 46) | public static FieldEvent fieldPersistedEvent(Field field) {
method fieldResetEvent (line 53) | public static FieldEvent fieldResetEvent(Field field) {
method FieldEvent (line 59) | private FieldEvent(EventType<? extends Event> eventType, Field field) {
method getField (line 64) | public final Field getField() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/event/FormEvent.java
class FormEvent (line 32) | public final class FormEvent extends Event {
method formPersistedEvent (line 46) | public static FormEvent formPersistedEvent(Form form) {
method formResetEvent (line 53) | public static FormEvent formResetEvent(Form form) {
method FormEvent (line 59) | private FormEvent(EventType<? extends Event> eventType, Form form) {
method getForm (line 64) | public final Form getForm() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/event/GroupEvent.java
class GroupEvent (line 32) | public final class GroupEvent extends Event {
method groupPersistedEvent (line 46) | public static GroupEvent groupPersistedEvent(Group group) {
method groupResetEvent (line 53) | public static GroupEvent groupResetEvent(Group group) {
method GroupEvent (line 59) | private GroupEvent(EventType<? extends Event> eventType, Group group) {
method getGroup (line 64) | public final Group getGroup() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/BooleanField.java
class BooleanField (line 35) | public class BooleanField extends DataField<BooleanProperty, Boolean, Bo...
method BooleanField (line 47) | protected BooleanField(SimpleBooleanProperty valueProperty, SimpleBool...
method validateRequired (line 64) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/DataField.java
class DataField (line 48) | public abstract class DataField<P extends Property, V, F extends Field<F...
method fromString (line 81) | @Override
method DataField (line 117) | protected DataField(P valueProperty, P persistentValueProperty) {
class AbstractStringConverter (line 143) | protected static abstract class AbstractStringConverter<V> extends Str...
method toString (line 144) | @Override
class StringConverterAdapter (line 150) | private static class StringConverterAdapter<V> extends AbstractStringC...
method StringConverterAdapter (line 153) | public StringConverterAdapter(ValueTransformer<V> valueTransformer) {
method fromString (line 157) | @Override
method format (line 172) | public F format(StringConverter<V> newValue) {
method format (line 191) | public F format(StringConverter<V> newValue, String errorMessage) {
method format (line 214) | @Deprecated
method format (line 235) | @Deprecated
method format (line 259) | public F format(String errorMessage) {
method validate (line 281) | @SafeVarargs
method bind (line 298) | public F bind(P binding) {
method unbind (line 313) | public F unbind(P binding) {
method setBindingMode (line 323) | public void setBindingMode(BindingMode newValue) {
method persist (line 335) | public void persist() {
method reset (line 349) | public void reset() {
method validateRequired (line 365) | protected boolean validateRequired(String newValue) {
method validate (line 376) | public boolean validate() {
method translate (line 439) | public void translate(TranslationService service) {
method getUserInput (line 446) | public String getUserInput() {
method userInputProperty (line 450) | public StringProperty userInputProperty() {
method getValue (line 454) | public V getValue() {
method valueProperty (line 458) | public P valueProperty() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/DateField.java
class DateField (line 39) | public class DateField extends DataField<ObjectProperty<LocalDate>, Loca...
method DateField (line 52) | public DateField(ObjectProperty<LocalDate> valueProperty, ObjectProper...
method bind (line 62) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/DoubleField.java
class DoubleField (line 34) | public class DoubleField extends DataField<DoubleProperty, Double, Doubl...
method DoubleField (line 46) | protected DoubleField(SimpleDoubleProperty valueProperty, SimpleDouble...
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Element.java
class Element (line 38) | public abstract class Element<E extends Element<E>> {
method id (line 54) | public E id(String newValue) {
method styleClass (line 67) | public E styleClass(String... newValue) {
method span (line 80) | public E span(int newValue) {
method span (line 93) | public E span(ColSpan newValue) {
method getSpan (line 98) | public int getSpan() {
method spanProperty (line 102) | public IntegerProperty spanProperty() {
method getID (line 106) | public String getID() {
method idProperty (line 110) | public StringProperty idProperty() {
method getStyleClass (line 114) | public ObservableList<String> getStyleClass() {
method styleClassProperty (line 118) | public ListProperty<String> styleClassProperty() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Field.java
class Field (line 63) | public abstract class Field<F extends Field<F>> extends Element<F> imple...
method Field (line 174) | protected Field() {
method ofPasswordType (line 208) | public static PasswordField ofPasswordType(String defaultValue) {
method ofPasswordType (line 220) | public static PasswordField ofPasswordType(StringProperty binding) {
method ofStringType (line 232) | public static StringField ofStringType(String defaultValue) {
method ofStringType (line 244) | public static StringField ofStringType(StringProperty binding) {
method ofDoubleType (line 256) | public static DoubleField ofDoubleType(double defaultValue) {
method ofDoubleType (line 268) | public static DoubleField ofDoubleType(DoubleProperty binding) {
method ofIntegerType (line 280) | public static IntegerField ofIntegerType(int defaultValue) {
method ofIntegerType (line 292) | public static IntegerField ofIntegerType(IntegerProperty binding) {
method ofBooleanType (line 304) | public static BooleanField ofBooleanType(boolean defaultValue) {
method ofBooleanType (line 316) | public static BooleanField ofBooleanType(BooleanProperty binding) {
method ofMultiSelectionType (line 331) | public static <T> MultiSelectionField<T> ofMultiSelectionType(List<T> ...
method ofMultiSelectionType (line 344) | public static <T> MultiSelectionField<T> ofMultiSelectionType(List<T> ...
method ofMultiSelectionType (line 360) | public static <T> MultiSelectionField<T> ofMultiSelectionType(ListProp...
method ofSingleSelectionType (line 375) | public static <T> SingleSelectionField<T> ofSingleSelectionType(List<T...
method ofSingleSelectionType (line 388) | public static <T> SingleSelectionField<T> ofSingleSelectionType(List<T...
method ofSingleSelectionType (line 404) | public static <T> SingleSelectionField<T> ofSingleSelectionType(ListPr...
method ofDate (line 414) | public static DateField ofDate(LocalDate defaultValue) {
method ofDate (line 424) | public static DateField ofDate(ObjectProperty<LocalDate> binding) {
method required (line 437) | public F required(boolean newValue) {
method required (line 452) | public F required(String errorMessage) {
method editable (line 474) | public F editable(boolean newValue) {
method label (line 490) | public F label(String newValue) {
method labelDescription (line 509) | public F labelDescription(Node newValue) {
method labelDescription (line 528) | public F labelDescription(String newValue) {
method valueDescription (line 547) | public F valueDescription(Node newValue) {
method valueDescription (line 566) | public F valueDescription(String newValue) {
method asLabel (line 576) | private Label asLabel(String text, String styleClass) {
method tooltip (line 594) | public F tooltip(String newValue) {
method placeholder (line 615) | public F placeholder(String newValue) {
method render (line 633) | public F render(SimpleControl<F> newValue) {
method render (line 647) | public F render(Supplier<SimpleControl<F>> newValue) {
method setBindingMode (line 659) | public abstract void setBindingMode(BindingMode newValue);
method translate (line 672) | public void translate(TranslationService newValue) {
method updateElement (line 700) | protected void updateElement(StringProperty displayProperty, StringPro...
method updateElement (line 722) | void updateElement(Node node, StringProperty keyProperty) {
method validate (line 750) | protected abstract boolean validate();
method getPlaceholder (line 752) | public String getPlaceholder() {
method placeholderProperty (line 756) | public StringProperty placeholderProperty() {
method getLabel (line 760) | public String getLabel() {
method labelProperty (line 764) | public StringProperty labelProperty() {
method getTooltip (line 768) | public String getTooltip() {
method tooltipProperty (line 772) | public StringProperty tooltipProperty() {
method isValid (line 776) | public boolean isValid() {
method validProperty (line 780) | public BooleanProperty validProperty() {
method hasChanged (line 784) | public boolean hasChanged() {
method changedProperty (line 788) | public BooleanProperty changedProperty() {
method isRequired (line 792) | public boolean isRequired() {
method requiredProperty (line 796) | public BooleanProperty requiredProperty() {
method isEditable (line 800) | public boolean isEditable() {
method editableProperty (line 804) | public BooleanProperty editableProperty() {
method isI18N (line 808) | public boolean isI18N() {
method getRenderer (line 812) | public SimpleControl<F> getRenderer() {
method getErrorMessages (line 820) | public List<String> getErrorMessages() {
method errorMessagesProperty (line 824) | public ListProperty<String> errorMessagesProperty() {
method addEventHandler (line 838) | public Field addEventHandler(EventType<FieldEvent> eventType, EventHan...
method removeEventHandler (line 862) | public Field removeEventHandler(EventType<FieldEvent> eventType, Event...
method fireEvent (line 878) | protected void fireEvent(FieldEvent event) {
method getLabelDescription (line 890) | public Node getLabelDescription() {
method getValueDescription (line 894) | public Node getValueDescription() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Form.java
class Form (line 51) | public class Form {
method Form (line 93) | private Form(Group... groups) {
method of (line 129) | public static Form of(Group... sections) {
method title (line 144) | public Form title(String newValue) {
method i18n (line 162) | public Form i18n(TranslationService newValue) {
method binding (line 183) | public Form binding(BindingMode newValue) {
method translate (line 195) | protected void translate() {
method persist (line 216) | public void persist() {
method reset (line 231) | public void reset() {
method setChangedProperty (line 245) | protected void setChangedProperty() {
method setValidProperty (line 254) | protected void setValidProperty() {
method setPersistableProperty (line 263) | protected void setPersistableProperty() {
method getGroups (line 267) | public List<Group> getGroups() {
method getElements (line 271) | public List<Element> getElements() {
method getFields (line 278) | public List<Field> getFields() {
method hasChanged (line 287) | public boolean hasChanged() {
method changedProperty (line 291) | public BooleanProperty changedProperty() {
method isValid (line 295) | public boolean isValid() {
method validProperty (line 299) | public BooleanProperty validProperty() {
method isPersistable (line 303) | public boolean isPersistable() {
method persistableProperty (line 307) | public BooleanProperty persistableProperty() {
method getTitle (line 311) | public String getTitle() {
method titleProperty (line 315) | public StringProperty titleProperty() {
method isI18N (line 319) | public boolean isI18N() {
method addEventHandler (line 333) | public Form addEventHandler(EventType<FormEvent> eventType, EventHandl...
method removeEventHandler (line 357) | public Form removeEventHandler(EventType<FormEvent> eventType, EventHa...
method fireEvent (line 373) | protected void fireEvent(FormEvent event) {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/FormElement.java
type FormElement (line 26) | public interface FormElement {
method persist (line 27) | void persist();
method reset (line 29) | void reset();
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Group.java
class Group (line 46) | public class Group {
method Group (line 75) | protected Group(Element... elements) {
method of (line 106) | public static Group of(Element... elements) {
method translate (line 120) | protected void translate(TranslationService newValue) {
method persist (line 137) | public void persist() {
method reset (line 154) | public void reset() {
method setChangedProperty (line 169) | private void setChangedProperty() {
method setValidProperty (line 180) | private void setValidProperty() {
method getElements (line 187) | public List<Element> getElements() {
method hasChanged (line 191) | public boolean hasChanged() {
method changedProperty (line 195) | public BooleanProperty changedProperty() {
method isValid (line 199) | public boolean isValid() {
method validProperty (line 203) | public BooleanProperty validProperty() {
method isI18N (line 207) | public boolean isI18N() {
method addEventHandler (line 221) | public Group addEventHandler(EventType<GroupEvent> eventType, EventHan...
method removeEventHandler (line 245) | public Group removeEventHandler(EventType<GroupEvent> eventType, Event...
method fireEvent (line 261) | protected void fireEvent(GroupEvent event) {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/IntegerField.java
class IntegerField (line 35) | public class IntegerField extends DataField<IntegerProperty, Integer, In...
method IntegerField (line 47) | protected IntegerField(SimpleIntegerProperty valueProperty, SimpleInte...
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/MultiSelectionField.java
class MultiSelectionField (line 45) | public class MultiSelectionField<V> extends SelectionField<V, MultiSelec...
method MultiSelectionField (line 68) | protected MultiSelectionField(ListProperty<V> items, List<Integer> sel...
method items (line 117) | public MultiSelectionField<V> items(List<V> newValue, List<Integer> ne...
method items (line 135) | public MultiSelectionField<V> items(List<V> newValue) {
method validate (line 149) | @SafeVarargs
method select (line 166) | public MultiSelectionField<V> select(int index) {
method deselect (line 182) | public MultiSelectionField<V> deselect(int index) {
method bind (line 202) | public MultiSelectionField<V> bind(ListProperty<V> itemsBinding, ListP...
method unbind (line 221) | public MultiSelectionField<V> unbind(ListProperty<V> itemsBinding, Lis...
method setBindingMode (line 231) | public void setBindingMode(BindingMode newValue) {
method persist (line 243) | public void persist() {
method reset (line 257) | public void reset() {
method validateRequired (line 270) | protected boolean validateRequired() {
method validate (line 281) | public boolean validate() {
method getSelection (line 294) | public ObservableList<V> getSelection() {
method selectionProperty (line 298) | public ListProperty<V> selectionProperty() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/NodeElement.java
class NodeElement (line 28) | public class NodeElement<N extends Node> extends Element {
method of (line 31) | public static <T extends Node> NodeElement<T> of(T node) {
method NodeElement (line 35) | protected NodeElement(N node) {
method getNode (line 42) | public N getNode() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/PasswordField.java
class PasswordField (line 36) | public class PasswordField extends DataField<StringProperty, String, Pas...
method PasswordField (line 47) | protected PasswordField(SimpleStringProperty valueProperty, SimpleStri...
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Section.java
class Section (line 37) | public class Section extends Group {
method Section (line 61) | private Section(Element... elements) {
method of (line 78) | public static Section of(Element... elements) {
method title (line 93) | public Section title(String newValue) {
method translate (line 106) | protected void translate(TranslationService newValue) {
method collapse (line 131) | public Section collapse(boolean newValue) {
method collapsedProperty (line 136) | public BooleanProperty collapsedProperty() {
method isCollapsed (line 140) | public boolean isCollapsed() {
method getTitle (line 144) | public String getTitle() {
method titleProperty (line 148) | public StringProperty titleProperty() {
method collapsible (line 158) | public Section collapsible(boolean newValue) {
method isCollapsible (line 163) | public boolean isCollapsible() {
method collapsibleProperty (line 167) | public BooleanProperty collapsibleProperty() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/SelectionField.java
class SelectionField (line 35) | public abstract class SelectionField<V, F extends SelectionField<V, F>> ...
method SelectionField (line 52) | protected SelectionField(ListProperty<V> items) {
method validateRequired (line 61) | protected abstract boolean validateRequired();
method validate (line 76) | protected boolean validate(List<String> errorMessages) {
method getItems (line 109) | public ObservableList getItems() {
method itemsProperty (line 113) | public ListProperty<V> itemsProperty() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/SingleSelectionField.java
class SingleSelectionField (line 44) | public class SingleSelectionField<V> extends SelectionField<V, SingleSel...
method SingleSelectionField (line 67) | protected SingleSelectionField(ListProperty<V> items, int selection) {
method items (line 113) | public SingleSelectionField<V> items(List<V> newValue, int newSelectio...
method items (line 133) | public SingleSelectionField<V> items(List<V> newValue) {
method validate (line 147) | @SafeVarargs
method select (line 164) | public SingleSelectionField<V> select(int index) {
method deselect (line 179) | public SingleSelectionField<V> deselect() {
method bind (line 199) | public SingleSelectionField<V> bind(ListProperty<V> itemsBinding, Obje...
method unbind (line 218) | public SingleSelectionField<V> unbind(ListProperty<V> itemsBinding, Ob...
method setBindingMode (line 228) | public void setBindingMode(BindingMode newValue) {
method persist (line 240) | public void persist() {
method reset (line 254) | public void reset() {
method validateRequired (line 267) | protected boolean validateRequired() {
method validate (line 278) | public boolean validate() {
method getSelection (line 291) | public V getSelection() {
method selectionProperty (line 295) | public ObjectProperty<V> selectionProperty() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/StringField.java
class StringField (line 36) | public class StringField extends DataField<StringProperty, String, Strin...
method StringField (line 50) | protected StringField(SimpleStringProperty valueProperty, SimpleString...
method multiline (line 72) | public StringField multiline(boolean newValue) {
method isMultiline (line 77) | public boolean isMultiline() {
method multilineProperty (line 81) | public BooleanProperty multilineProperty() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/util/BindingMode.java
type BindingMode (line 31) | public enum BindingMode {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/util/ResourceBundleService.java
class ResourceBundleService (line 32) | public class ResourceBundleService extends TranslationService {
method ResourceBundleService (line 36) | public ResourceBundleService(ResourceBundle rb) {
method changeLocale (line 47) | public void changeLocale(ResourceBundle newValue) {
method translate (line 59) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/util/TranslationService.java
class TranslationService (line 34) | public abstract class TranslationService {
method translate (line 46) | public abstract String translate(String key);
method addListener (line 48) | public void addListener(Runnable listener) {
method removeListener (line 52) | public void removeListener(Runnable listener) {
method notifyListeners (line 60) | protected void notifyListeners() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/util/ValueTransformer.java
type ValueTransformer (line 31) | @Deprecated
method transform (line 34) | T transform(String input);
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/CustomValidator.java
class CustomValidator (line 33) | public class CustomValidator<T> extends RootValidator<T> {
method CustomValidator (line 37) | protected CustomValidator(Predicate<T> callback, String errorMessage) {
method forPredicate (line 42) | public static <E> CustomValidator<E> forPredicate(Predicate<E> callbac...
method validate (line 49) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/DoubleRangeValidator.java
class DoubleRangeValidator (line 30) | public class DoubleRangeValidator extends CustomValidator<Double> {
method DoubleRangeValidator (line 32) | private DoubleRangeValidator(double min, double max, String errorMessa...
method between (line 52) | public static DoubleRangeValidator between(double min, double max, Str...
method atLeast (line 70) | public static DoubleRangeValidator atLeast(double min, String errorMes...
method upTo (line 84) | public static DoubleRangeValidator upTo(double max, String errorMessag...
method exactly (line 99) | public static DoubleRangeValidator exactly(double value, String errorM...
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/IntegerRangeValidator.java
class IntegerRangeValidator (line 30) | public class IntegerRangeValidator extends CustomValidator<Integer> {
method IntegerRangeValidator (line 32) | private IntegerRangeValidator(int min, int max, String errorMessage) {
method between (line 52) | public static IntegerRangeValidator between(int min, int max, String e...
method atLeast (line 70) | public static IntegerRangeValidator atLeast(int min, String errorMessa...
method upTo (line 84) | public static IntegerRangeValidator upTo(int max, String errorMessage) {
method exactly (line 99) | public static IntegerRangeValidator exactly(int value, String errorMes...
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/RegexValidator.java
class RegexValidator (line 32) | public class RegexValidator extends RootValidator<String> {
method RegexValidator (line 36) | private RegexValidator(String pattern, String errorMessage) throws Pat...
method forPattern (line 55) | public static RegexValidator forPattern(String pattern, String errorMe...
method forEmail (line 70) | public static RegexValidator forEmail(String errorMessage) {
method forURL (line 85) | public static RegexValidator forURL(String errorMessage) {
method forAlphaNumeric (line 100) | public static RegexValidator forAlphaNumeric(String errorMessage) {
method validate (line 107) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/RootValidator.java
class RootValidator (line 29) | abstract class RootValidator<T> implements Validator<T> {
method RootValidator (line 33) | protected RootValidator(String errorMessage) {
method createResult (line 45) | protected ValidationResult createResult(boolean result) {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/SelectionLengthValidator.java
class SelectionLengthValidator (line 32) | public class SelectionLengthValidator<E> extends CustomValidator<Observa...
method SelectionLengthValidator (line 34) | private SelectionLengthValidator(int min, int max, String errorMessage) {
method between (line 53) | public static <T> SelectionLengthValidator<T> between(int min, int max...
method atLeast (line 76) | public static <T> SelectionLengthValidator<T> atLeast(int min, String ...
method upTo (line 94) | public static <T> SelectionLengthValidator<T> upTo(int max, String err...
method exactly (line 109) | public static <T> SelectionLengthValidator<T> exactly(int value, Strin...
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/StringLengthValidator.java
class StringLengthValidator (line 30) | public class StringLengthValidator extends CustomValidator<String> {
method StringLengthValidator (line 32) | private StringLengthValidator(int min, int max, String errorMessage) {
method between (line 51) | public static StringLengthValidator between(int min, int max, String e...
method atLeast (line 74) | public static StringLengthValidator atLeast(int min, String errorMessa...
method upTo (line 92) | public static StringLengthValidator upTo(int max, String errorMessage) {
method exactly (line 107) | public static StringLengthValidator exactly(int value, String errorMes...
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/ValidationResult.java
class ValidationResult (line 30) | public class ValidationResult {
method ValidationResult (line 35) | ValidationResult(boolean result, String errorMessage) {
method getErrorMessage (line 44) | public String getErrorMessage() {
method getResult (line 48) | public boolean getResult() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/Validator.java
type Validator (line 30) | public interface Validator<T> {
method validate (line 32) | ValidationResult validate(T input);
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleBooleanControl.java
class SimpleBooleanControl (line 38) | public class SimpleBooleanControl extends SimpleControl<BooleanField> {
method initializeParts (line 53) | @Override
method layoutParts (line 68) | @Override
method setupBindings (line 93) | @Override
method setupValueChangedListeners (line 104) | @Override
method setupEventHandlers (line 118) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleCheckBoxControl.java
class SimpleCheckBoxControl (line 41) | public class SimpleCheckBoxControl<V> extends SimpleControl<MultiSelecti...
method initializeParts (line 56) | @Override
method layoutParts (line 71) | @Override
method setupBindings (line 97) | @Override
method setupValueChangedListeners (line 108) | @Override
method setupEventHandlers (line 135) | @Override
method createCheckboxes (line 146) | protected void createCheckboxes() {
method setupCheckboxBindings (line 165) | protected void setupCheckboxBindings() {
method setupCheckboxEventHandlers (line 174) | protected void setupCheckboxEventHandlers() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleComboBoxControl.java
class SimpleComboBoxControl (line 39) | public class SimpleComboBoxControl<V> extends SimpleControl<SingleSelect...
method initializeParts (line 57) | @Override
method layoutParts (line 75) | @Override
method setupBindings (line 106) | @Override
method setupValueChangedListeners (line 119) | @Override
method setupEventHandlers (line 141) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleControl.java
class SimpleControl (line 41) | public abstract class SimpleControl<F extends Field> extends GridPane im...
method setField (line 61) | public void setField(F field) {
method initializeParts (line 73) | @Override
method layoutParts (line 91) | @Override
method setupBindings (line 107) | public void setupBindings() {
method setupValueChangedListeners (line 114) | @Override
method toggleTooltip (line 141) | protected void toggleTooltip(Node reference) {
method toggleTooltip (line 153) | protected void toggleTooltip(Node reference, Control below) {
method updateStyle (line 183) | protected void updateStyle(PseudoClass pseudo, boolean newValue) {
method addStyleClass (line 191) | public void addStyleClass(String name) {
method removeStyleClass (line 199) | public void removeStyleClass(String name) {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleDateControl.java
class SimpleDateControl (line 37) | public class SimpleDateControl extends SimpleControl<DateField> {
method initializeParts (line 44) | @Override
method layoutParts (line 56) | @Override
method setupBindings (line 83) | @Override
method setupEventHandlers (line 99) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleDoubleControl.java
class SimpleDoubleControl (line 32) | public class SimpleDoubleControl extends SimpleNumberControl<DoubleField...
method initializeParts (line 37) | @Override
method setupValueChangedListeners (line 48) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleIntegerControl.java
class SimpleIntegerControl (line 32) | public class SimpleIntegerControl extends SimpleNumberControl<IntegerFie...
method initializeParts (line 37) | @Override
method setupValueChangedListeners (line 48) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleListViewControl.java
class SimpleListViewControl (line 39) | public class SimpleListViewControl<V> extends SimpleControl<MultiSelecti...
method initializeParts (line 57) | @Override
method layoutParts (line 80) | @Override
method setupBindings (line 106) | @Override
method setupValueChangedListeners (line 117) | @Override
method setupEventHandlers (line 149) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleNumberControl.java
class SimpleNumberControl (line 39) | public abstract class SimpleNumberControl<F extends DataField, D extends...
method initializeParts (line 61) | @Override
method layoutParts (line 76) | @Override
method setupBindings (line 120) | @Override
method setupEventHandlers (line 135) | @Override
method setupValueChangedListeners (line 152) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimplePasswordControl.java
class SimplePasswordControl (line 41) | public class SimplePasswordControl extends SimpleControl<PasswordField> {
method initializeParts (line 68) | @Override
method layoutParts (line 87) | @Override
method setupBindings (line 133) | @Override
method setupValueChangedListeners (line 151) | @Override
method obfuscate (line 160) | protected String obfuscate(String input) {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleRadioButtonControl.java
class SimpleRadioButtonControl (line 42) | public class SimpleRadioButtonControl<V> extends SimpleControl<SingleSel...
method initializeParts (line 59) | @Override
method layoutParts (line 75) | @Override
method setupBindings (line 101) | @Override
method setupValueChangedListeners (line 112) | @Override
method setupEventHandlers (line 137) | @Override
method createRadioButtons (line 148) | protected void createRadioButtons() {
method setupRadioButtonBindings (line 171) | protected void setupRadioButtonBindings() {
method setupRadioButtonEventHandlers (line 180) | protected void setupRadioButtonEventHandlers() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleTextControl.java
class SimpleTextControl (line 41) | public class SimpleTextControl extends SimpleControl<StringField> {
method initializeParts (line 64) | @Override
method layoutParts (line 83) | @Override
method setupBindings (line 139) | @Override
method setupValueChangedListeners (line 163) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/renderer/FormRenderer.java
class FormRenderer (line 39) | public class FormRenderer extends VBox implements ViewMixin {
method FormRenderer (line 49) | public FormRenderer(Form form) {
method getUserAgentStylesheet (line 55) | @Override
method initializeParts (line 63) | @Override
method layoutParts (line 79) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/renderer/GroupRenderer.java
class GroupRenderer (line 32) | public class GroupRenderer extends GroupRendererBase {
method GroupRenderer (line 40) | protected GroupRenderer(Group group) {
method initializeParts (line 48) | @Override
method layoutParts (line 56) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/renderer/GroupRendererBase.java
class GroupRendererBase (line 40) | public abstract class GroupRendererBase<V extends Group> extends StackPa...
method initializeParts (line 55) | @Override
method layoutParts (line 63) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/renderer/SectionRenderer.java
class SectionRenderer (line 32) | public class SectionRenderer extends GroupRendererBase<Section> {
method SectionRenderer (line 42) | protected SectionRenderer(Section section) {
method initializeParts (line 50) | @Override
method layoutParts (line 59) | @Override
method setupValueChangedListeners (line 75) | @Override
method setupBindings (line 85) | @Override
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/util/ColSpan.java
type ColSpan (line 29) | public enum ColSpan {
method ColSpan (line 41) | ColSpan(int span) {
method valueOf (line 45) | public int valueOf() {
FILE: formsfx-core/src/main/java/com/dlsc/formsfx/view/util/ViewMixin.java
type ViewMixin (line 30) | public interface ViewMixin {
method getStylesheets (line 37) | List<String> getStylesheets();
method init (line 43) | default void init() {
method initializeSelf (line 55) | default void initializeSelf() {}
method initializeParts (line 60) | void initializeParts();
method layoutParts (line 65) | void layoutParts();
method setupEventHandlers (line 70) | default void setupEventHandlers() {}
method setupValueChangedListeners (line 75) | default void setupValueChangedListeners() {}
method setupBindings (line 80) | default void setupBindings() {}
method addStylesheetFiles (line 88) | default void addStylesheetFiles(String... stylesheetFile) {
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/structure/FieldTest.java
class FieldTest (line 50) | @Ignore
method beforeClass (line 53) | @BeforeClass
method validTest (line 62) | @Test
method singleSelectionTest (line 80) | @Test
method multiSelectionTest (line 102) | @Test
method multilineTest (line 121) | @Test
method dataBindingTest (line 131) | @Test
method selectionBindingTest (line 168) | @Ignore
method propertiesTest (line 195) | @Ignore
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/structure/FormTest.java
class FormTest (line 37) | public class FormTest {
method beforeSuite (line 43) | @Before
method generateFormTest (line 48) | @Test
method translationTest (line 71) | @Test
method changeTest (line 89) | @Test
method validationTest (line 117) | @Test
method persistableTest (line 155) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/structure/SectionTest.java
class SectionTest (line 30) | public class SectionTest {
method collapseTest (line 32) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/util/ResourceBundleServiceTest.java
class ResourceBundleServiceTest (line 36) | public class ResourceBundleServiceTest {
method translateTest (line 41) | @Test
method changeLocaleTest (line 52) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/CustomValidatorTest.java
class CustomValidatorTest (line 30) | public class CustomValidatorTest {
method customTest (line 32) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/DoubleRangeValidatorTest.java
class DoubleRangeValidatorTest (line 32) | public class DoubleRangeValidatorTest {
method betweenTest (line 34) | @Test
method atLeastTest (line 55) | @Test
method upToTest (line 66) | @Test
method exactlyTest (line 77) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/IntegerRangeValidatorTest.java
class IntegerRangeValidatorTest (line 32) | public class IntegerRangeValidatorTest {
method betweenTest (line 34) | @Test
method atLeastTest (line 55) | @Test
method upToTest (line 66) | @Test
method exactlyTest (line 77) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/RegexValidatorTest.java
class RegexValidatorTest (line 34) | public class RegexValidatorTest {
method regexTest (line 36) | @Test
method emailTest (line 52) | @Test
method urlTest (line 62) | @Test
method alphaNumericTest (line 72) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/SelectionLengthValidatorTest.java
class SelectionLengthValidatorTest (line 33) | public class SelectionLengthValidatorTest {
method betweenTest (line 35) | @Test
method atLeastTest (line 60) | @Test
method upToTest (line 81) | @Test
method exactlyTest (line 91) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/StringLengthValidatorTest.java
class StringLengthValidatorTest (line 32) | public class StringLengthValidatorTest {
method betweenTest (line 34) | @Test
method atLeastTest (line 60) | @Test
method upToTest (line 81) | @Test
method exactlyTest (line 91) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/view/controls/SimpleControlTest.java
class SimpleControlTest (line 45) | @Ignore
method before (line 48) | @BeforeClass
method itemsTest (line 57) | @Test
method styleTest (line 102) | @Test
FILE: formsfx-core/src/test/java/com/dlsc/formsfx/view/renderer/RendererTest.java
class RendererTest (line 45) | @Ignore
method before (line 48) | @BeforeClass
method formTest (line 57) | @Test
method groupTest (line 68) | @Test
method sectionTest (line 82) | @Test
FILE: formsfx-demo/src/main/java/com/dlsc/formsfx/demo/Demo.java
class Demo (line 15) | public class Demo extends Application {
method start (line 17) | @Override
method main (line 30) | public static void main(String[] args) {
FILE: formsfx-demo/src/main/java/com/dlsc/formsfx/demo/model/Country.java
class Country (line 16) | public class Country {
method getName (line 45) | public String getName() {
method nameProperty (line 49) | public StringProperty nameProperty() {
method getIso (line 53) | public String getIso() {
method isoProperty (line 57) | public StringProperty isoProperty() {
method isIndependence (line 61) | public boolean isIndependence() {
method independenceProperty (line 65) | public BooleanProperty independenceProperty() {
method getIndependenceDay (line 69) | public LocalDate getIndependenceDay() {
method independenceDayProperty (line 73) | public ObjectProperty<LocalDate> independenceDayProperty() {
method getCurrencyShort (line 77) | public String getCurrencyShort() {
method currencyShortProperty (line 81) | public StringProperty currencyShortProperty() {
method getCurrencyLong (line 85) | public String getCurrencyLong() {
method currencyLongProperty (line 89) | public StringProperty currencyLongProperty() {
method getPopulation (line 93) | public int getPopulation() {
method populationProperty (line 97) | public IntegerProperty populationProperty() {
method getArea (line 101) | public double getArea() {
method areaProperty (line 105) | public DoubleProperty areaProperty() {
method getTld (line 109) | public String getTld() {
method tldProperty (line 113) | public StringProperty tldProperty() {
method getDateFormat (line 117) | public String getDateFormat() {
method dateFormatProperty (line 121) | public StringProperty dateFormatProperty() {
method getDriverSide (line 125) | public String getDriverSide() {
method driverSideProperty (line 129) | public ObjectProperty<String> driverSideProperty() {
method getTimeZone (line 133) | public String getTimeZone() {
method timeZoneProperty (line 137) | public StringProperty timeZoneProperty() {
method getSummerTimeZone (line 141) | public String getSummerTimeZone() {
method summerTimeZoneProperty (line 145) | public StringProperty summerTimeZoneProperty() {
method getAllSides (line 149) | public ObservableList<String> getAllSides() {
method allSidesProperty (line 153) | public ListProperty<String> allSidesProperty() {
method getAllCities (line 157) | public ObservableList<String> getAllCities() {
method allCitiesProperty (line 161) | public ListProperty<String> allCitiesProperty() {
method getAllCapitals (line 165) | public ObservableList<String> getAllCapitals() {
method allCapitalsProperty (line 169) | public ListProperty<String> allCapitalsProperty() {
method getAllContinents (line 173) | public ObservableList<String> getAllContinents() {
method allContinentsProperty (line 177) | public ListProperty<String> allContinentsProperty() {
method getContinents (line 181) | public ObservableList<String> getContinents() {
method continentsProperty (line 185) | public ListProperty<String> continentsProperty() {
method getCapital (line 189) | public String getCapital() {
method capitalProperty (line 193) | public ObjectProperty<String> capitalProperty() {
method getGermanCities (line 197) | public ObservableList<String> getGermanCities() {
method germanCitiesProperty (line 201) | public ListProperty<String> germanCitiesProperty() {
FILE: formsfx-demo/src/main/java/com/dlsc/formsfx/demo/model/DemoModel.java
class DemoModel (line 27) | public final class DemoModel {
method getFormInstance (line 50) | public Form getFormInstance() {
method createForm (line 61) | private void createForm() {
method translate (line 165) | public void translate(String language) {
method getCountry (line 178) | public Country getCountry() {
FILE: formsfx-demo/src/main/java/com/dlsc/formsfx/demo/view/RootPane.java
class RootPane (line 24) | public class RootPane extends BorderPane implements ViewMixin {
method RootPane (line 67) | public RootPane(DemoModel model) {
method initializeSelf (line 75) | @Override
method initializeParts (line 84) | @Override
method setupBindings (line 125) | @Override
method setupValueChangedListeners (line 136) | @Override
method setupEventHandlers (line 150) | @Override
method layoutParts (line 178) | @Override
Condensed preview — 101 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (407K chars).
[
{
"path": ".github/workflows/build.yml",
"chars": 1199,
"preview": "name: Build\non:\n push:\n branches:\n - master-11\n pull_request:\n types: [opened, synchronize, reopened]\njobs:"
},
{
"path": ".github/workflows/release.yml",
"chars": 2289,
"preview": "name: Release\n\non:\n workflow_dispatch:\n inputs:\n version:\n description: \"Release version\"\n requir"
},
{
"path": ".gitignore",
"chars": 24,
"preview": ".idea\n/target\n*.iml\n/out"
},
{
"path": ".mvn/wrapper/maven-wrapper.properties",
"chars": 1020,
"preview": "# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements. See the NOTICE f"
},
{
"path": "CHANGELOG.md",
"chars": 7812,
"preview": "# Change Log\n\n## [11.4.1](https://github.com/dlsc-software-consulting-gmbh/formsfx/tree/11.4.1) (2019-09-01)\n[Full Chang"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 9416,
"preview": "[](https://www.j"
},
{
"path": "docs/Project Report.pages/Metadata/BuildVersionHistory.plist",
"chars": 741,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "docs/Project Report.pages/Metadata/DocumentIdentifier",
"chars": 36,
"preview": "A198DE43-9C62-4C8D-9A85-4BBB04C88780"
},
{
"path": "docs/architecture.xml",
"chars": 4143,
"preview": "<mxfile userAgent=\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1"
},
{
"path": "formsfx-core/.gitignore",
"chars": 13,
"preview": "/target\n*.iml"
},
{
"path": "formsfx-core/pom.xml",
"chars": 7185,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xmlns:xsi=\"http://www"
},
{
"path": "formsfx-core/src/license/apache20/header.txt",
"chars": 526,
"preview": "Licensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the "
},
{
"path": "formsfx-core/src/license/apache20/license.txt",
"chars": 11357,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "formsfx-core/src/license/licenses.properties",
"chars": 28,
"preview": "apache20=Apache License 2.0\n"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/event/FieldEvent.java",
"chars": 2146,
"preview": "package com.dlsc.formsfx.model.event;\n\n/*-\n * ========================LICENSE_START=================================\n * "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/event/FormEvent.java",
"chars": 2107,
"preview": "package com.dlsc.formsfx.model.event;\n\n/*-\n * ========================LICENSE_START=================================\n * "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/event/GroupEvent.java",
"chars": 2146,
"preview": "package com.dlsc.formsfx.model.event;\n\n/*-\n * ========================LICENSE_START=================================\n * "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/BooleanField.java",
"chars": 2364,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/DataField.java",
"chars": 14979,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/DateField.java",
"chars": 2655,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/DoubleField.java",
"chars": 2120,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Element.java",
"chars": 3510,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Field.java",
"chars": 30946,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Form.java",
"chars": 12165,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/FormElement.java",
"chars": 945,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Group.java",
"chars": 8650,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/IntegerField.java",
"chars": 2134,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/MultiSelectionField.java",
"chars": 9856,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/NodeElement.java",
"chars": 1329,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/PasswordField.java",
"chars": 2260,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/Section.java",
"chars": 4897,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/SelectionField.java",
"chars": 3670,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/SingleSelectionField.java",
"chars": 9759,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/structure/StringField.java",
"chars": 2799,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/util/BindingMode.java",
"chars": 1161,
"preview": "package com.dlsc.formsfx.model.util;\n\n/*-\n * ========================LICENSE_START=================================\n * F"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/util/ResourceBundleService.java",
"chars": 1790,
"preview": "package com.dlsc.formsfx.model.util;\n\n/*-\n * ========================LICENSE_START=================================\n * F"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/util/TranslationService.java",
"chars": 1939,
"preview": "package com.dlsc.formsfx.model.util;\n\n/*-\n * ========================LICENSE_START=================================\n * F"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/util/ValueTransformer.java",
"chars": 1143,
"preview": "package com.dlsc.formsfx.model.util;\n\n/*-\n * ========================LICENSE_START=================================\n * F"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/CustomValidator.java",
"chars": 1684,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/DoubleRangeValidator.java",
"chars": 3591,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/IntegerRangeValidator.java",
"chars": 3597,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/RegexValidator.java",
"chars": 4256,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/RootValidator.java",
"chars": 1558,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/SelectionLengthValidator.java",
"chars": 4072,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/StringLengthValidator.java",
"chars": 3924,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/ValidationResult.java",
"chars": 1531,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/model/validators/Validator.java",
"chars": 1064,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleBooleanControl.java",
"chars": 4021,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleCheckBoxControl.java",
"chars": 5745,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleComboBoxControl.java",
"chars": 5016,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleControl.java",
"chars": 6559,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleDateControl.java",
"chars": 3341,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleDoubleControl.java",
"chars": 1867,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleIntegerControl.java",
"chars": 1879,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleListViewControl.java",
"chars": 5395,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleNumberControl.java",
"chars": 5062,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimplePasswordControl.java",
"chars": 5687,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleRadioButtonControl.java",
"chars": 5805,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/controls/SimpleTextControl.java",
"chars": 6324,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/renderer/FormRenderer.java",
"chars": 2414,
"preview": "package com.dlsc.formsfx.view.renderer;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/renderer/GroupRenderer.java",
"chars": 1724,
"preview": "package com.dlsc.formsfx.view.renderer;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/renderer/GroupRendererBase.java",
"chars": 3238,
"preview": "package com.dlsc.formsfx.view.renderer;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/renderer/SectionRenderer.java",
"chars": 2495,
"preview": "package com.dlsc.formsfx.view.renderer;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/util/ColSpan.java",
"chars": 1226,
"preview": "package com.dlsc.formsfx.view.util;\n\n/*-\n * ========================LICENSE_START=================================\n * Fo"
},
{
"path": "formsfx-core/src/main/java/com/dlsc/formsfx/view/util/ViewMixin.java",
"chars": 2556,
"preview": "package com.dlsc.formsfx.view.util;\n\n/*-\n * ========================LICENSE_START=================================\n * Fo"
},
{
"path": "formsfx-core/src/main/java/module-info.java",
"chars": 1203,
"preview": "/*-\n * ========================LICENSE_START=================================\n * FormsFX\n * %%\n * Copyright (C) 2017 - 2"
},
{
"path": "formsfx-core/src/main/resources/com/dlsc/formsfx/view/renderer/style.css",
"chars": 7018,
"preview": "/*******************\n * GENERAL STYLING *\n *******************/\n\n.formsfx-group {\n -fx-border-width: 1px;\n -fx-bor"
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/structure/FieldTest.java",
"chars": 7199,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/structure/FormTest.java",
"chars": 6627,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/structure/SectionTest.java",
"chars": 1336,
"preview": "package com.dlsc.formsfx.model.structure;\n\n/*-\n * ========================LICENSE_START================================="
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/util/ResourceBundleServiceTest.java",
"chars": 2084,
"preview": "package com.dlsc.formsfx.model.util;\n\n/*-\n * ========================LICENSE_START=================================\n * F"
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/CustomValidatorTest.java",
"chars": 1304,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/DoubleRangeValidatorTest.java",
"chars": 3060,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/IntegerRangeValidatorTest.java",
"chars": 2943,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/RegexValidatorTest.java",
"chars": 2774,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/SelectionLengthValidatorTest.java",
"chars": 3937,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/model/validators/StringLengthValidatorTest.java",
"chars": 3406,
"preview": "package com.dlsc.formsfx.model.validators;\n\n/*-\n * ========================LICENSE_START================================"
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/view/controls/SimpleControlTest.java",
"chars": 4764,
"preview": "package com.dlsc.formsfx.view.controls;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/test/java/com/dlsc/formsfx/view/renderer/RendererTest.java",
"chars": 3717,
"preview": "package com.dlsc.formsfx.view.renderer;\n\n/*-\n * ========================LICENSE_START=================================\n "
},
{
"path": "formsfx-core/src/test/resources/testbundle_de_CH.properties",
"chars": 77,
"preview": "form_title = Testformular\nsection_1_title = Erste Gruppe\nstring_label = Text\n"
},
{
"path": "formsfx-core/src/test/resources/testbundle_en_UK.properties",
"chars": 77,
"preview": "form_title = Test Form\nsection_1_title = First Section\nstring_label = String\n"
},
{
"path": "formsfx-demo/.gitignore",
"chars": 13,
"preview": "/target\n*.iml"
},
{
"path": "formsfx-demo/pom.xml",
"chars": 760,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xmlns:xsi=\"http://www"
},
{
"path": "formsfx-demo/src/main/java/com/dlsc/formsfx/demo/Demo.java",
"chars": 822,
"preview": "package com.dlsc.formsfx.demo;\n\nimport com.dlsc.formsfx.demo.model.DemoModel;\nimport com.dlsc.formsfx.demo.view.RootPane"
},
{
"path": "formsfx-demo/src/main/java/com/dlsc/formsfx/demo/model/Country.java",
"chars": 5933,
"preview": "package com.dlsc.formsfx.demo.model;\n\nimport javafx.beans.property.*;\nimport javafx.collections.FXCollections;\nimport ja"
},
{
"path": "formsfx-demo/src/main/java/com/dlsc/formsfx/demo/model/DemoModel.java",
"chars": 8914,
"preview": "package com.dlsc.formsfx.demo.model;\n\nimport com.dlsc.formsfx.model.structure.Field;\nimport com.dlsc.formsfx.model.struc"
},
{
"path": "formsfx-demo/src/main/java/com/dlsc/formsfx/demo/view/RootPane.java",
"chars": 9061,
"preview": "package com.dlsc.formsfx.demo.view;\n\nimport com.dlsc.formsfx.demo.model.DemoModel;\nimport com.dlsc.formsfx.model.structu"
},
{
"path": "formsfx-demo/src/main/java/module-info.java",
"chars": 130,
"preview": "module com.dlsc.formsfx.demo {\n\n requires javafx.controls;\n requires com.dlsc.formsfx;\n\n exports com.dlsc.forms"
},
{
"path": "formsfx-demo/src/main/resources/demo-locale_de_CH.properties",
"chars": 2262,
"preview": "capital_label = Hauptstadt\ngerman_cities_label = Deutschsprachige St\\u00e4dte\ncontinent_label = Kontinent\npopulation_lab"
},
{
"path": "formsfx-demo/src/main/resources/demo-locale_en_UK.properties",
"chars": 2140,
"preview": "capital_label = Capital\ngerman_cities_label = German-speaking Cities\ncontinent_label = Continent\npopulation_label = Popu"
},
{
"path": "formsfx-demo/src/main/resources/style.css",
"chars": 1942,
"preview": "@font-face {\n font-family: 'Flaticon';\n src: url(/flaticon.ttf);\n}\n.field-label-description,\n.field-value-descript"
},
{
"path": "jreleaser.yml",
"chars": 1321,
"preview": "#\n# SPDX-License-Identifier: Apache-2.0\n#\n# Copyright 2021 Dirk Lemmermann Software & Consulting (dlsc.com)\n#\n# Licensed"
},
{
"path": "mvnw",
"chars": 10283,
"preview": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Softwa"
},
{
"path": "mvnw.cmd",
"chars": 6733,
"preview": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software F"
},
{
"path": "pom.xml",
"chars": 2658,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xmlns:xsi=\"http://www"
}
]
// ... and 5 more files (download for full content)
About this extraction
This page contains the full source code of the dlemmermann/formsfx GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 101 files (375.7 KB), approximately 90.8k tokens, and a symbol index with 508 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.