Uma aplicação com SwingBean – Parte III
Na terceira parte do artigo serão vistos alguns detalhes que servirão para enriquecer a aplicação, como validadores, máscaras e dependência de componentes.
Introdução
Retomando a aplicação de cadastros de filmes, tem-se até agora um formulário contendo os dados para preenchimento dos dados contidos no bean Filme. Os objetivos dessa terceira parte são:
- Demonstrar como a adição de novos campos não requer mudanças no código responsável pelo formulário;
- Introduzir os validadores e máscaras;
- Adicionar campos que são dependentes de outros campos.
Adicionando novos campos
Uma das motivações ao se trabalhar com frameworks, independente da linguagem, é o fato de poder adicionar mudanças na aplicação afetando o menor trecho de código possível.
Para o exemplo atual, imagine que haja a necessidade de introdução de um novo campo: duração do filme.
Pode-se fazer essa adição em apenas dois passos extremamente simples:
- criação do atributo duração no bean Filme;
- adição do componente no xmldescriptor.
As listagens 01 e 02 demonstram como isso é feito.
//início do código de Filme.java
private String descricao;
private String duracao;
public Filme(){}
public final Date getDataDeLancamento() {
return dataDeLancamento;
}
//get e set para duracao
//restante do código de Filme.java
Listagem 01 – Filmes.java
<line>
<property name="genero" label="Gênero" … />
<property name="dataDeLancamento" label="Data de Nascimento" />
<property name="censura" />
<property name="duracao" mask="##h##m##s" label=”Duração” />
</line>
Listagem 02 – filme_xmldescriptor.xml
Atente-se para o detalhe dos métodos setDuracao e getDuracao, que são essenciais para o funcionamento da aplicação.
Ao ser executada, a aplicação já contém o novo campo, como indica a figura 01.
Figura 01
O campo duração possui uma máscara, como é possível ver na figura 01, “ h m s” que representam as horas, minutos e segundos de duração. (Poderia ter sido utilizada a notação padrão que é de apenas minutos, mas foi feito dessa maneira para representar melhor as máscaras.)
O que define essa máscara é a propriedade mask da tag responsável pelo campo no arquivo xml.
Configurando os validadores
Primeiramente é necessário definir as propriedades específicas de alguns dos campos – os que passarão pelo processo de validação.
Os campos título, diretor, gênero, censura e duração, a partir de agora, serão considerados obrigatórios. Para isso, basta apenas adicionar em cada uma de suas tags no xmldescriptor, o atributo mandatory=”true”. Por exemplo:
<property name="censura" mandatory="true" />
Com, isso, os labels de cada campo obrigatório ficarão em negrito, como mostra a figura 01.
Será definido também o tamanho mínimo do campo diretor para 3 caracteres, através do atributo minSize, e no máximo 200 por size:
<property name="diretor" mandatory="true" size=”200” minSize="3" />
Com isso já se tem um pequeno conjunto de restrições que serão avaliadas no momento da adição. É claro que para aplicações reais, valida-se o máximo de campos possível para evitar quaisquer tipos de dados inválidos a serem adicionados em um banco de dados, por exemplo.
O SwingBean contém classes responsáveis por gerenciar essas validações, assim como permite que os programadores criem suas próprias, ou seja, é possível dizer ao framework como validar o campo. Porém, por enquanto só será vista a ação padrão de validação de campos.
Com as restrições criadas, parte-se para a edição do código de CadastroFilme. É interessante destacar que as mudanças são mínimas; apenas a adição de um pequeno trecho já é suficiente para habilitar as validações de campo.
A listagem 03 mostra o que é necessário adicionar.
//início do código de CadastroFilme.java
ApplicationAction actionCadastra = new ApplicationAction(){
public void execute(){
Filme beanFilme = new Filme(); //novo
panelFilme.populateBean(beanFilme);
beanTableModel.addBean(beanFilme); //novo
System.out.println(beanFilme);
panelFilme.cleanForm();
}
};
ValidationAction vAction = new ValidationAction(panelFilme);
ApplicationAction actionValida = ActionChainFactory.createChainActions(vAction, actionCadastra);
JActButton bCadastra = new JActButton("Cadastrar", actionValida);
//restante do código de CadastroFilme.java
Listagem 03 – CadastroFilme.java
Até a segunda parte do artigo, a ação configurada no botão de cadastro (bCadastra) era actionCadastra.
Inicialmente cria-se uma instância de ValidationAction, que recebe panelFilme, como painél a ser validado. O construtor desta classe pode receber mais de um painél, caso seja necessário.
ValidationAction é uma subclasse de ApplicationAction, ou seja, trata-se de um evento como qualquer outro, porém, com capacidade de validar dados antes de ser tratado de acordo com as suas ações.
Em seguida, cria-se uma cadeia de ações com a fábrica ActionChainFactory, através de createChainActions passando por parâmetro vAction e actionCadastra.
A única troca a ser feita agora é o evento ao qual o botão bCadastra está relacionado, que nesse caso será a cadeia de ações criada anteriormente, actionValida.
Com isso, tem-se o evento de validação de campos configurado como primeiro da lista de eventos a serem executados. Se houver algum campo mal preenchido, as ações posteriores são ignoradas e é exibida uma mensagem para o usuário contendo todos os erros que devem ser corrigidos.
A figura 02 mostra a mensagem de erros caso todos os campos sejam deixados em branco.
Figura 02
Adicionando dependência de campos
Para tratar a situação, imagine que deva haver na aplicação, um campo checável que indica se o filme tem ou não um site na internet. Caso tenha, o campo para preenchimento do mesmo é habilitado.
Primeiramente deve-se adicionar dois atributos no bean Filme: comSite (boolean) e site (String), ambos com seus getters e setters. (Não será listado aqui o código, por se tratar do mesmo esquema visto na listagem 01, porém, o mesmo está disponível para download.)
O xmldescriptor também deverá ser alterado para adição dos dois campos, como indica a listagem 04.
<line>
<property name="genero" label="Gênero” … />
<property name="dataDeLancamento" label="Data de Nascimento" />
<property name="censura" mandatory="true" />
<property name="duracao" mask="##h##m##s" mandatory="true" label="Duração" />
<property name="site" />
<property name="comSite" dlu="50" />
</line>
Listagem 04 – filme_xmldescriptor.xml
O atributo dlu apenas define um tamanho fixo para o componente, visto que o checkbox ocupará apenas uma pequena parte do formulário, e não será necessário dividir um espaço em igual com os outros componentes da linha.
Com o xml definido, parte-se para a única adição necessária em CadastroFilme, de acordo com a listagem 05.
JScrollPane jScrollPane = new JScrollPane(beanTable);
beanTable.enableHeaderOrdering();
CheckBoxEnableAction cBEAction = new CheckBoxEnableAction(panelFilme, "comSite", "site");
panelFilme.associateAction("comSite", cBEAction);
ApplicationAction actionCadastra = new ApplicationAction(){
public void execute(){
Listagem 05 – CadastroFilme.java
Inicialmente cria-se uma instância da acão CheckBoxEnableAction, que recebe o painél ao qual o checkbox estará presente, seu nome (deve ser igual ao boolean criado no bean Filme) e o(s) nome(s) do(s) componente(s) que depende(m) dele.
Em seguida associa-se ao painél a ação através de panelFilme.associateAction.
A figura 03 mostra os campos criados.
Figura 03
Conclusões
Com esta terceira parte concluída, tem-se uma interface mais rica, com novos componentes e validação de campos.
Novos componentes e recursos do framework serão introduzidos nos próximos artigos.
Um grande abraço e até a próxima,
Adriano