Uma aplicação com SwingBean – Parte II
Nesta segunda parte serão introduzidos dois recursos a respeito do framework, que irão enriquecer a aplicação, o combo box model e o bean table.
Introdução
Na primeira parte do artigo, foi criado um painél para o cadastro de filmes. Para confirmar o sucesso do cadastro, era gerada uma saída no prompt de comando com os dados preenchidos. Com a criação de uma tabela, todos os registros cadastrados serão adicionados nela em tempo de execução.
Outro recurso interessante é a utilização do combo box model para cadastrar o gênero do filme de acordo com uma lista pré-definida.
A classe DefaultComboBoxModel
O gênero, na interface gráfica anterior, era preenchido em um campo de texto comum. Como há uma lista de gêneros já definida o recomendável é que o usuário apenas escolha-o ao invés de preenchê-lo, visto que “Comédia” e “Comedia” seriam tratados (a nível de banco de dados, por exemplo) como gêneros diferentes.
Para utilização de combobox no swingbean, é necessário criar uma classe contendo os registros que serão adicionados na lista de opções. A Listagem 01 apresenta essa classe.
package br.com.jm.forms.combomodels;
import javax.swing.DefaultComboBoxModel;
public class GeneroComboModel extends DefaultComboBoxModel{
public GeneroComboModel(){
addElement("Aventura");
addElement("Comédia");
addElement("Drama");
addElement("Ficção Científica");
addElement("Policial");
addElement("Suspense");
addElement("Terror");
}
}
Listagem 01
A classe GeneroComboModel extende DefaultComboBoxModel, que é uma das superclasses tratadas pelo framework.
Os elementos presentes na lista são adicionados em cada chamada a addElement.
Com isso tem-se um combo box compatível com o framework. Basta agora apenas uma alteração no xml responsável pelo painél, criado na primeira parte do artigo com o nome de filme_xmldescriptor.xml.
A tag que cuida do campo gênero deverá ficar da seguinte maneira:
<property name="genero" label="Gênero" comboModelClass="br.com.jm.forms.combomodels.GeneroComboModel" />, de forma que a classe criada seja buscada pelo framework.
Dessa forma o campo gênero ficará de acordo com a Figura 01.
Figura 01
Tabela de filmes cadastrados
Para a criação de uma tabela contendo os filmes cadastrados, deverá ser criado, assim como feito para o painél de cadastro, um arquivo XML contendo a descrição da mesma, de acordo com a listagem 02.
<?xml version="1.0" encoding="UTF-8"?>
<beanDescriptor>
<line>
<property name="titulo" label="Título" readOnly="true" />
<property name="diretor" readOnly="true" />
<property name="genero" label="Gênero" readOnly="true" />
</line>
</beanDescriptor>
Listagem 02
Apenas para demonstração de seu uso, serão utilizados apenas três campos, sendo o name referente ao nome da propriedade presente no bean, o label ao título exibido no header da tabela e o readOnly, assim como o próprio nome diz, não permite a edição da linha em tempo de execução (somente leitura).
Com o XML criado, parte-se para a edição do código da classe CadastroFilme para configurar a tabela.
A Listagem 03 mostra como deve ficar o código do método getFormCadastro.
public JPanel getFormCadastro(){
GenericFieldDescriptor descriptor = XMLDescriptorFactory.getFieldDescriptor(Filme.class, "filme_xmldescriptor.xml", "Cadastro de Filmes");
final JBeanPanel<Filme> panelFilme = new JBeanPanel<Filme>(Filme.class, descriptor);
//novo
TableFieldDescriptor tableFieldDescriptor = XMLDescriptorFactory.getTableFieldDescriptor(Filme.class, "filmetable_xmldescriptor.xml", "Filmes Cadastrados");
final BeanTableModel<Filme> beanTableModel = new BeanTableModel<Filme>(tableFieldDescriptor);
final JBeanTable beanTable = new JBeanTable(beanTableModel);
JScrollPane jScrollPane = new JScrollPane(beanTable);
beanTable.enableHeaderOrdering();
//
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();
}
};
JActButton bCadastra = new JActButton("Cadastrar", actionCadastra);
ApplicationAction actionLimpa = new ApplicationAction(){
public void execute(){
panelFilme.cleanForm();
}
};
JActButton bLimpaCampos = new JActButton("Limpar campos", actionLimpa);
JPanel buttons = new JPanel();
buttons.add(bCadastra);
buttons.add(bLimpaCampos);
JPanel jPanel = new JPanel(new BorderLayout());
jPanel.add(panelFilme, BorderLayout.NORTH);
jPanel.add(jScrollPane, BorderLayout.CENTER); //novo
jPanel.add(buttons, BorderLayout.SOUTH);
return jPanel;
}
Listagem 03
Será descrito apenas o que há de novo no código.
Inicialmente criou-se uma instância de TableFieldDescriptor, que é o responsável por ler o XML da tabela. Em seguida, essa instância foi passada para BeanTableModel, que é o modelo da tabela que será usado para criação da mesma.
A tabela então é criada como instância de JBeanTable fazendo uso do modelo gerado, e passada para o construtor de JScrollPane, pronta para ser adicionada.
O método enableHeaderOrdering faz com que a tabela seja ordenada pelo cabeçalho (para o Windows XP com um duplo clique no header escolhido).
Dentro do método actionCadastra foi criada uma instância de Filme para ser tratada pelo painél de cadastro e pela tabela. Na primeira parte do artigo essa variável era definida na classe. A alteração se deve ao fato da adição à tabela ser prejudicada caso o bean seja uma variável de classe.
Para fazer com que cada cadastro seja adicionado à tabela basta chamar o método addBean passando o bean que foi populado pelo framework.
A tabela é então adicionada entre o painél de cadastro e o painél de botões no final do método e ficará de acordo com a figura 2.
Figura 02
Conclusões
Com os dois recursos introduzidos nesta segunda parte do artigo Uma aplicação com SwingBean, foi possível enriquecer a interface gráfica da aplicação e nos próximos artigos serão abordados outros recursos interessantes.
* O código-fonte da aplicação, com as alterações após a segunda parte do artigo, está disponível para download.
Um grande abraço e até a próxima,
Adriano