JavaFX Form Validation

Will Hoover java.whoover at gmail.com
Tue Jun 12 08:50:27 PDT 2012


Although you may disagree... 

The issue I see with a lot of validation frameworks is that they UI control
centric. The problem with this approach is that it's very redundant. If you
use the same entity/domain model fields in multiple controls (which happens
more frequently than one would think- different forms) then the developer is
left with the responsibility of ensuring the consistency of the validations
across different UI controls. It also makes it a bit more difficult to
manage validations between multiple UI controls (group validation) because
an additional mechanism has to be introduced to handle cross-control
validation. The potential of producing conflicting validation logic as an
application increases in complexity becomes a much higher risk.

Some see validation that impacts an applications domain models as being
somewhat invasive, but I think that having multiple validation points in UI
controls is far more problematic. In addition it's not perceived as invasive
when it integrates with an existing entity-neutral framework ;) Florian's
comment about JSR-349 looks like it may be promising. I really like the idea
of integration of existing validation points from the Bean perspective. A
lot of other frameworks have adopted this approach (like OpenJPA's use of
JSR-303). I agree JSR-303 is a little dated and lacks a robust validation
scheme, but maybe an active JavaFX role in JSR-349 may be an alternative?

As you mention, the downside to this approach are cases where the validation
isn't domain model specific. Although, IMHO, the use of validation that
doesn't pertain to domain models is more of an exception to the rule versus
the rule itself... My initial thought to resolve this would be to provide
hooks into the Property API that allows you to define validation annotations
that are not using a domain model:

1) With POJO domain model + a reusable BeanValidationAdaptor (similar to
com.sun.javafx.fxml.BeanAdaptor):
public class Person {
	@NotNull
	@Pattern(regexp="\\(\\d{3}\\)\\d{3}-\\d{4}")
	private String phoneNumber;

	public String getPhoneNumber(){return phoneNumber;}
	public void setPhoneNumber(String phoneNumber){this.phoneNumber =
phoneNumber;}
}
BeanValidationAdaptor<Person> bva = new
BeanValidationAdaptor<>(personInstance);
TextField tf = new TextField();
Bindings.bindValidator(bva.stringProperty("phoneNumber"),
tf.textProperty());

2) With JavaFX specific model:
public class PersonBean {
	@NotNull
	@Pattern(regexp="\\(\\d{3}\\)\\d{3}-\\d{4}")
	private StringProperty phoneNumber = new SimpleStringProperty();

	public String getPhoneNumber(){return phoneNumber.get();}
	public void setPhoneNumber(String
phoneNumber){phoneNumber.set(phoneNumber);}
	public StringProperty phoneNumberProperty() {return phoneNumber;}
}
TextField tf = new TextField();
Bindings.bindValidator(personBeanInstance.phoneNumberProperty(),
tf.textProperty());

3) With agonistic control (JavaFX provided ValidationProperty +
ValidationEvent):
ValidationProperty<String> vp = new ValidationProperty<>() {
	@NotNull
	@Pattern(regexp="\\(\\d{3}\\)\\d{3}-\\d{4}")
	@Override
	public void validate(ValidationEvent<String> event) {
		// if needed, additional fine-grain validation could also
occur here using 
		// event.getTarget(), event.getSource(), and event.consume()
		return super.validate(event);
	}
};
TextField tf = new TextField();
Bindings.bindValidator(vp, tf.textProperty());

It would make bindings integration seem a bit more natural and
self-contained, yet still provide the reusability of domain model validation
annotations across tiers. All validation would be referenced in either
domain model annotations or within annotations within the property itself.
UI controls would not have to contain any validation definitions and would
simply use internal triggers from underlying properties to propagate visual
aides to the end user.

-----Original Message-----
From: openjfx-dev-bounces at openjdk.java.net
[mailto:openjfx-dev-bounces at openjdk.java.net] On Behalf Of Jonathan Giles
Sent: Sunday, June 10, 2012 7:52 PM
To: openjfx-dev at openjdk.java.net
Subject: JavaFX Form Validation

Hi all,

I'm currently in the very, very early stages of developing a validation API
for future inclusion into JavaFX. I thought rather than get too far into the
research and development of a proof of concept, I would see what you all
think. Any feedback now would be very useful.

Essentially, there are a few common styles related to form validation. 
Some of the more likely approaches include:

  * The 'JGoodies Validation framework' [1] approach, where the
    developer provides a Validator that will then run over the form and
    gather feedback to return to the user (for example, it would test
    that the 'name field' is not empty, and that the email address is of
    the correct style - if either of these rules are invalid, the
    Validator would return ValidationMessage instances inside a
    ValidationResult). If validation fails the user is shown the text
    out of the ValidationMessage feedback, otherwise the form would
    submit as per usual. This validation may happen at a number of times
    (during form submission, when focus is lost, as a key is typed,
    etc). The nice thing about this approach is that the Validator can
    be a part of the domain model, the presentation model, or a separate
    thing altogether.
  * The JSR-303 approach which uses annotations to indicate the rules
    applicable to each field. These annotations are on the domain model,
    and therefore assumes that the form is directly tied to a domain
    object (which may not always be correct). I think the JSR-303 API is
    too complex for what is needed in JavaFX, but a similar
    implementation could be developed with a simpler API that follows
    this approach.
  * For lack of a better reference point, the FXForm approach [3] which
    encapsulates the validation inside a Form object that can be placed
    in the scene. I know this isn't explicitly (in the case of FXForm)
    about validation, but I think it is another approach to consider.

So, what does JavaFX need out of a validation framework? It's really five
things (I think):

 1. A way for developers to validate a form by providing some means of
    specifying rules, as well as a way to specify when it runs, how it
    is visually represented, etc.
 2. A way for the validation to impact upon the visual state of the form
    (using consistent CSS pseudoclass states / style classes, as well as
    by showing custom overlays, error messages beside the component (or
    grouped together at the top of the form)). There must be API to
    specify all of this.
 3. Convenient API to simplify the validation process [3] (e.g.
    isEmpty(String), isAlphanumeric(String), etc, etc, etc).
 4. An API that does not require it be integrated with UI controls.
    Doing so would prevent 3rd party UI controls to be able to be
    validated without also implementing the API, which may prove
    burdensome. Instead, the validation API should be separate.
 5. A means to integrate nicely with the bindings and properties API
    present in JavaFX today.

Of the three approaches above, my personal preference is to follow the
JGoodies approach as I think it is the most powerful and flexible. 
However, nothing is set in stone and I want to learn what others think.

Note that at present this research does not extend to considering whether
there should be API related to automatically generating a form from a
(JavaFX) bean (and making use of the validation API to ensure the input is
correct). However, I am not against discussing this topic as well, as long
as it too integrates nicely with the rules above, as well as the validation
API itself, obviously. This research may full into requirement three above.

[1] http://www.jgoodies.com/freeware/libraries/validation/
[2] https://github.com/dooApp/FXForm2
[3]
http://www.jarvana.com/jarvana/view/com/jgoodies/validation/2.0.1/validation
-2.0.1-javadoc.jar!/com/jgoodies/validation/util/ValidationUtils.html

Thanks,
-- Jonathan



More information about the openjfx-dev mailing list