![]() |
|
Spaces home Patrice SecheressePhotosProfileFriendsMore ![]() | ![]() |
Patrice SecheressePatrice Secheresse - IT Experience
August 25 BeansBinding: validation errorTo continue the previous blog, I will add some explanations about the validator. For example, I want to validate the age to ensure that it is between 0 and 150. All you need to do is to create a class that extends Validator and implements the method validate(). Here the class AgeValidator: 1: public class AgeValidator extends Validator<Integer> { 2: 3: @Override4: public Result validate(Integer value) { 5: if (value < 0 || value > 150) { 6: return new Result(1, "The age must be between 0 and 150. The value " + value + " is incorrect."); 7: }8: return null; 9: } 10: }The method returns a null value if the value is valid. If an error occurs, you create a result object with a code and/or a description. The code can be useful when you internationalise the application. It could be any object or null. To add the validator, you just have to set it in the binding: binding.setValidator(new AgeValidator()); So, if you add these lines at the end of our previous run method:
The result will be: Failure VALIDATION_FAILED: org.jdesktop.beansbinding.Validator$Result [errorCode=1, description=The age must be between 0 and 150. The value 151 is incorrect.] You can notice that the type of error is now VALIDATION_FAILED instead of CONVERSION_FAILED. The validation occurs after the conversion. The idea is to work with the source object type to keep the validation independent of the UI. However, this lead to 2 different systems:
You have to check the failure and display the error depending of the type. Using an unified way to send a failure would have been simpler. The full code of the main class is: 1: public class Main { 2: 3: Person person; 4: Text text; 5: 6: public Main() { 7: person = new Person("John", 21); 8: text = new Text(); 9: } 10: 11: /** 12: * @param args the command line arguments 13: */ 14: public static void main(String[] args) { 15: Main test = new Main(); 16: test.run(); 17: 18: } 19: 20: private void run() { 21: Property ageProperty = BeanProperty.create("age"); 22: Property textProperty = BeanProperty.create("text"); 23: // bind the persone age to a text component 24: Binding binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, 25: person, ageProperty, text, textProperty);26: binding.setValidator(new AgeValidator()); 27: binding.addBindingListener(new AbstractBindingListener() { 28: 29: @Override30: public void syncFailed(Binding binding, SyncFailure failure) { 31: System.err.println("Failure " + failure); 32: } 33: }); 34: binding.bind(); 35: 36: text.setText("22"); // print value 37: text.setText("22 and half"); // incorrect value, print failure 38: text.setText("151"); //incorrect value, print failure 39: text.setText("-1"); //incorrect value, print failure 40: }August 21 BeansBinding: conversion error
For a long time I haven't posted anything on this blog. One reason is the finalization of the project VolunteerBase. Since the installation, no news... Another reason is my new job in OrderMate since March. I am working on an advanced Point Of Sale software for restaurant, café and hospitality. Everything is written in Java, including the new back end which present a rich client interface based on Swing. The recent evolution uses the BeansBinding library. An excellent blog here details the basic usage of this library and this Java One Technical Session is a good introduction. An important aspect is the mechanism to convert and validate a property and I will enlarge on it today. To illustrate a basic problem with conversion and validation, I use an integer property bind to a text component. I use the same kind Person class from the John O'Conner blog, with name and age property: 1: public class Person { 2: 3: private String name; 4: private int age; 5: 6: public Person() { 7: } 8: 9: public Person(String name, int age) { 10: this.name = name; 11: this.age = age; 12: } 13: 14: public int getAge() { 15: return age; 16: } 17: 18: public void setAge(int age) { 19: this.age = age; 20: } 21: 22: public String getName() { 23: return name; 24: } 25: 26: public void setName(String name) { 27: this.name = name; 28: } 29: }The text component is a simple JavaBeans component with only one 'text' property and the property change support. The value is printed each time it is set. The idea is to emulate a JText component. 1: public class Text { 2: 3: private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this); 4: private String text; 5: 6: public String getText() { 7: return text; 8: } 9: 10: public void setText(String text) { 11: String oldText = this.text; 12: this.text = text; 13: System.out.println("Set text to " + text); 14: propertySupport.firePropertyChange("text", oldText, text); 15: } 16: 17: public void addPropertyChangeListener(PropertyChangeListener listener) { 18: propertySupport.addPropertyChangeListener(listener); 19: } 20: 21: public void removePropertyChangeListener(PropertyChangeListener listener) { 22: propertySupport.removePropertyChangeListener(listener); 23: } 24: }Now, I want to bind the age to the text and simulate the users entry by setting the value of the text. First, create the properties and bind them: the source is the bean from the data source, the target is generally a visual component. Be careful to respect this, a validator is designed to check that a target value is valid. For today, we won't use a validator:
That's it, any modifications of the text property will go through a default converter and set the age property of the persone:
But what happens if the value is incorrect?
The answer is... nothing. The default converter from String to integer uses Integer.parseInt((String)value) which throws a
The last solution offers the possibility to react to an incorrect value, for example, in a GUI it will disable the OK button and will set the text field in a different color. In this simple example, it will simply display the error with the added code below:
This code will print: Failure CONVERSION_FAILED: java.lang.NumberFormatException: For input string: "22 and half" The full code of the main class is here: 1: public class Main { 2: 3: Person person; 4: Text text; 5: 6: public Main() { 7: person = new Person("John", 21); 8: text = new Text(); 9: } 10: 11: /** 12: * @param args the command line arguments 13: */ 14: public static void main(String[] args) { 15: Main test = new Main(); 16: test.run(); 17: 18: } 19: 20: private void run() { 21: Property ageProperty = BeanProperty.create("age"); 22: Property textProperty = BeanProperty.create("text"); 23: // bind the persone age to a text component 24: Binding binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, 25: person, ageProperty, text, textProperty); 26: binding.bind();27: binding.addBindingListener(new AbstractBindingListener() { 28: 29: @Override30: public void syncFailed(Binding binding, SyncFailure failure) { 31: System.err.println("Failure " + failure); 32: } 33: }); 34: 35: text.setText("22"); // print value 36: text.setText("22 and half"); // incorrect value, print failure 37: } 38: }
This conclude this post, the next step will be adding a validator. November 24 Stable version of VolunteerBaseThis version 0.6 of volunteerbase contains fixes and minor improvements, the project is now in a stable phase. The Wiki user guide has a comprehensive coverage of all the functions. The package has been upgraded to Tomcat 6.0 and the distribution can use Java 5.0 or 6.0. October 19 Volunteerbase project specifications completedWith the release 0.5, the project is now covering the initial specifications. The next big steps will be the functional tests, acceptance test and the documentation. The test by the new SPW Australia team should add some new ideas and further evolutions. October 04 Release 0.4 of VolunteerBase projectAfter a long iteration, finally the 0.4 is published. The biggest challenge was to include a reporting capability without using heavy weight framework. After some issues with JPA and iReport, I have decided to choose a simpler and well known solution with Apache Fop. The idea of xsl-format looks good. It uses the css style and is able to generate many output (html, pdf, png, RTF etc...). It's really handful to separate the content of the presentation and it gives the possibility to customize easily the report. However it's not very efficient to create rapid report with complex structure. Associated with a lack of tools and the future css3, I not sure of the future of this product. The release contains also a bunch of bug fixes. The new function is the volunteer contribution management. The features are:
The next feature in 0.5 will be an individual report to give a situation of the volunteer contributions.
|
|
||||||||||||||||||
|
|