Antes de falar sobre essas coisas eu recomendo que você cheque os seguintes artigos:
Validando Controls do JavaFX usando Bean Validation
Com Bean Validation 2.0 temos o "unwrap" automático de propriedades JavaFX. Isso significa que se você tiver um campo do tipo ObservableValue o validator vai conseguir tirar o valor real e aplicar a validação. No entanto, os campos de control do JavaFX ainda não são suportados, então se você tentar validar os campos diretamente você vai ter uma exceção:
Isso acontece por uqe a implementação do validator não sabe como retirar valores de um controller JavaFX. O que precisamos é criar uma classe que implementa javax.validation.valueextraction.ValueExtractor. Precisamos também usar o tipo do controle que essa classe vai saber tirar o valor (usar genéricos para isso), criar o método que faz a atual extração do valor (tipo um getText em um TextField) e, por fim, usar a anotação javax.validation.valueextraction.ExtractedValue para configurar o tipo que é tirado do control(String, Integer, LocalDate...). Para evitar passos adicionais usamos a anotação javax.validation.valueextraction.UnwrapByDefault na nossa implementação. As nossas classes para tirar valores do DatePicker e do TextField estão abaixo:
Value Extractor para o DatePicker |
Value Extractor para o TextField |
Finalmente, precisamos registrar isso com o framework de validação. Há
Finally we must register it in within the bean validation framework. There are a couple of algumas formas de fazer isso, escolhemos o modo com SPI que é criar um arquivo com o nome META-INF/services/javax.validation.valueextraction.ValueExtractor com o nome das classes dos nossos ValueExtractors:
Poderíamos ter uma extensão de bean validation para os controles do JavaFX, assim não teríamos que criar novamente. Se você sabe de algum projeto assim me fale que eu menciono aqui!
Você provavelmente quer mostrar os erros para os usuários quando os valores que ele entrou não são válidos. Uma vez que você tenha acesso a classe Validator no controller você simplesmente pode chamar o método validate no controller e mostrar aos usuários os erros de validação em um label, por exemplo. Eu pessoalmente não gosto dessa solução pois eu acho que é muito intrusivo já que você terá que modificar a view para incluir mais labels só para a validação. Uma solução mais simples é mostrar um tooltip com o erro de validação no campo que deu problema. Poderíamos também mostrar um dialog ou bordar o campo de vermelho, mas só mostramos o tooltip mesmo:
Conteúdo do arquivo META-INF/services/javax.validation.valueextraction.ValueExtractor |
Poderíamos ter uma extensão de bean validation para os controles do JavaFX, assim não teríamos que criar novamente. Se você sabe de algum projeto assim me fale que eu menciono aqui!
Mostrar os erros de validation para os usuários
Você provavelmente quer mostrar os erros para os usuários quando os valores que ele entrou não são válidos. Uma vez que você tenha acesso a classe Validator no controller você simplesmente pode chamar o método validate no controller e mostrar aos usuários os erros de validação em um label, por exemplo. Eu pessoalmente não gosto dessa solução pois eu acho que é muito intrusivo já que você terá que modificar a view para incluir mais labels só para a validação. Uma solução mais simples é mostrar um tooltip com o erro de validação no campo que deu problema. Poderíamos também mostrar um dialog ou bordar o campo de vermelho, mas só mostramos o tooltip mesmo:
Método showValidationErrors pega o controle que tem erro de validação adiciona um tooltip e mostra |
Para mostrar o tooltip precisamos acessar o controle em sí e para isso precisamos fazer um pouco de reflexão
CDI, Bean Validation e JavaFX
Our maven project and its files |
Essas são as dependências que eu adicionei ao pom.xml:
These are all dependencies required to use bean validation and CDI on a JavaFX application |
O código de uma aplicação de exemplo pode ser encontrado no meu github github. Abaixo você pode ver como a validação usando tooltips funciona na aplicação:
Por quey isso é importante?
Para mais exemplos de validação você pode ver essa pull request do Hendrik Ebbers para o projeto hibernate validator.