• Nenhum resultado encontrado

A aplicação de exemplo

No documento Java Magazine - Edição 039.pdf (páginas 54-56)

Apresentaremos a partir de agora um exemplo de uso do pattern Presentation

 Model  com a API JGoodies Binding. O

código completo está disponível para download no site da Java Magazine (para rodar o exemplo, basta executar a classe Programa).

Além da API Binding você vai precisar das APIs Forms e Looks do JGoodies. Para obtê-las, no site do projeto ( jgoodies.com) vá

até a seçãoDownload e clique emLibraries.

Lá você terá acesso aos arquivos zipados de todas as APIs, contendo exemplos, do- cumentação, código-fonte e os JARs que devem ser incluídos no classpath da sua aplicação.

 Apresentando a aplicação

O exemplo que vamos construir é um cadastro de usuários conforme apresen- tado na Figura 3. É mostrada uma lista contendo todos os usuários cadastrados; as informações do usuário selecionado são exibidas à direita. Cada usuário possui quatro atributos: o nome, o cargo, e dois indicadores definindo se é administrador e se tem acesso ao controle de permissões da aplicação. O acesso ao controle de permis- sões só é possível para administradores.

Um título no lado direito apresenta qual usuário estamos editando. Se nenhum estiver selecionado, é apresentado o texto “Nenhum usuário selecionado” e todos os componentes de edição ficam desabi- litados.

 A classe Usuario

Começaremos construindo o exem- plo pela classe Usuario, mostrada na Listagem 1. Para essa classe JavaBean, o ponto mais importante a destacar é a emissão de eventos, que é realizada quando os dados do usuário são alterados. Precisamos implementar isso porque as classes da API Binding exigem que os objetos manipulados sejam observáveis3. Assim sendo, o primeiro passo é fazer a classe Usuario herdar da classe Model(pa- cotecom.jgoodies.binding.beans); em seguida alteramos todos os métodos setXxx() para que chamem firePropertyChange() e, dessa forma, avisem que a propriedade em questão mudou seu valor.

 A classe Presentation Model 

A segunda classe que vamos desenvolver chama-se CadastroUsuarioPresentationModel (Listagem 2). Conforme vimos naFigura 1, essa classe deve possuir

uma referência para a clas-

se Service Layer, que é o

único meio de comunica- ção da GUI com o resto do software. Assim, o cons- trutor da classe recebe e guarda um objeto do tipo CadastroUsuarioServiceLayer, que é explicado mais adiante.

Ainda no construtor, repare a cha- mada de dois métodos: iniciaModelos() e iniciaLogicaApresentacao(). É nesses métodos que o estado e a lógica da GUI começam a surgir. Para entender o código, acompanhe aFigura 4 e veja como a API Binding está sendo usada. A Tabela 1 apresenta um resumo dos objetos citados a seguir.

O métodoiniciaModelos() começa criando o objetousuarioSelectionInList, a partir de um ListModel (usuarioListModel) e um ValueModel (usuarioSelecionadoHolder):

usuarioListModel = new ArrayListModel();

usuarioSelecionadoHolder = new ValueHolder(null, true); usuarioSelectionInList = new SelectionInList((ListModel)

usuarioListModel, usuarioSelecionadoHolder);

Embora ainda não tenhamos explicado a

3Basicamente, um objeto éobservável  quando mudan-

ças nele emitem eventos. O objeto que escuta esses even- tos chama-seobservador . Esses são conceitos trazidos pelo patternObserver  do livro “Design Patterns” [Gamma et al.].

Figura 3. Tela de cadastro de usuários.

Listagem 1.Classe de modelo Usuario.

import com.jgoodies.binding.beans.Model; public class Usuario extends Model {

public static final String PROPERTY_NOME = “nome”; public static final String PROPERTY_CARG O = “cargo”;

public static final String PROPERTY_ADMI NISTRADOR = “administrado r”;

public static final String PROPERTY_CONTROLE_PERMISSAO = “controlePermissao”; private String nome;

private String cargo;

private boolean isAdministr ador; private boolean isControleP ermissao; public String getNome() {

return nome; }

public void setNome(Str ing nome) { String valorAntigo = this.nome; this.nome = nome;

// Todos os metodos set lançam eventos...

this.fireProp ertyChange(P ROPERTY_NOME, valorAntigo , this.nome); }

/*...Os outros metodos get/set são similares */ }

54  Java Magazine•Edição 39 import com.jgoodies.binding.beans.*; import com.jgoodies.binding.list.*; import com.jgoodies.binding.value.*; import javax.swing.*; import java.awt.event.ActionEvent; import java.beans.*; import java.util.*;

public class CadastroUsuarioPresentationModel extends Model { public static final String TITULO_SEM_SELECAO =

“Nenhum usuário selecionado.”;

public static final String TITULO_COM_SELECAO = “Detalhes de “; private CadastroUsuarioServiceLayer serviceLayer;

private ArrayListModel usuarioListModel;

private BeanAdapter usuarioSelecionadoBeanAdapter; private SelectionInList usuarioSelectionInList; private SelectionInList cargoSelectionInList; private ValueHolder usuarioSelecionadoHolder; private ValueHolder tituloHolder;

private ValueHolder usuarioDisponivelHolder; private ValueHolder campoPermissaoDisponivelHolder; private Action adicionarAction;

private Action removerAction; private Action salvarAction;

public CadastroUsuarioPresentationModel( CadastroUsuarioServiceLayer serviceLayer) { this.serviceLayer = serviceLayer;   iniciaModelos();   iniciaLogicaApresentacao(); }

private void iniciaModelos() {

usuarioListModel = new ArrayListModel();

usuarioSelecionadoHolder = new ValueHolder(null, true); usuarioSelectionInList = new SelectionInList(

(ListModel) usuarioListModel, usuarioSelecionadoHolder); usuarioSelecionadoBeanAdapter = new BeanAdapter(

usuarioSelecionadoHolder, true);

ArrayListModel cargoListModel = new ArrayListModel(   Arrays.asList(Cargos.TODOS));

cargoSelectionInList = new SelectionInList( (ListModel) cargoListModel, getCargoHolder()); tituloHolder = new ValueHolder();

usuarioDisponivelHolder = new ValueHolder(); campoPermissaoDisponivelHolder = new ValueHolder(); adicionarAction = new AdicionarAction();

removerAction = new RemoverAction(); salvarAction = new SalvarAction(); }

private void iniciaLogicaApresentacao() { ObservadorSelecaoUsuario observadorSelecao = new ObservadorSelecaoUsuario();   usuarioSelecionadoHolder.addValueChangeListener(   observadorSelecao);   observadorSelecao.propertyChange(null); ObservadorNomeUsuario observadorNome = new ObservadorNomeUsuario();   this.getNomeHolder().addValueChangeListener(observadorNome);   observadorNome.propertyChange(null); ObservadorCampoAdmin observadorAdmin = new ObservadorCampoAdmin();   this.getAdminHolder().addValueChangeListener(   observadorAdmin);   observadorAdmin.propertyChange(null);

PropertyConnector connector = new PropertyConnector( usuarioDisponivelHolder, “value”, removerAction, “   enabled”);

  connector.updateProperty2();

List usuarios = serviceLayer.buscaUsuarios();   usuarioListModel.addAll(usuarios);

}

/* Metodos get omitidos */ private void adicionaUsuario() {

Usuario novoUsuario = new Usuario(“Novo Usuário”, null);   usuarioListModel.add(novoUsuario);

}

private void removeUsuario() {

int indice = usuarioSelectionInList.getSelectionIndex(); if (indice != -1) {

  usuarioListModel.remove(indice); }

}

private void salvaUsuarios() {

List lista = Collections.unmodifiableList(usuarioListModel);   serviceLayer.salvaUsuarios(lista);

}

private void habilitaCampos() { boolean enabled =

usuarioSelecionadoHolder.getValue() != null;   usuarioDisponivelHolder.setValue(enabled);   habilitaCampoControlePermissao();

}

private void habilitaCampoControlePermissao() { Usuario selecionado = (

Usuario) usuarioSelecionadoHolder.getValue(); boolean enabled = selecionado !=

null && selecionado.isAdministrador();

  campoPermissaoDisponivelHolder.setValue(enabled); }

/* Inner classes de ações */

private class AdicionarAction extends AbstractAction { public void actionPerformed(ActionEvent e) {

  adicionaUsuario(); }

}

private class RemoverAction extends AbstractAction { public void actionPerformed(ActionEvent e) {   removeUsuario();

} }

private class SalvarAction extends AbstractAction { public void actionPerformed(ActionEvent e) {   salvaUsuarios();

} }

/* Inner classes de observadores */

private class ObservadorNomeUsuario implements PropertyChangeListener {

public void propertyChange(PropertyChangeEvent evt) { if (getUsuarioSelecionadoHolder().getValue() == null) {   getTituloHolder().setValue(TITULO_SEM_SELECAO); } else { getTituloHolder().setValue(TITULO_COM_SELECAO +   getNomeHolder().getValue()); }

// Emite um evento de mudança para que a GUI reflita o novo // nome.

  usuarioListModel.fireContentsChanged(

  usuarioSelectionInList.getSelectionIndex()); }

}

private class ObservadorSelecaoUsuario implements PropertyChangeListener {

public void propertyChange(PropertyChangeEvent evt) {   habilitaCampos();

} }

private class ObservadorCampoAdmin implements PropertyChangeListener {

public void propertyChange(PropertyChangeEvent evt) {   habilitaCampoControlePermissao();

} } }

Listagem 2.Classe CadastroUsuarioPresentationModel, onde fica o estado e a lógica da GUI.

Edição 39• Java Magazine 55

2007

No documento Java Magazine - Edição 039.pdf (páginas 54-56)