devmedia - versão para impressão

Upload: genaldo-aragao

Post on 11-Oct-2015

68 views

Category:

Documents


0 download

TRANSCRIPT

  • DevMedia - Verso para impresso

    Swing + Beans Binding

    Marcelo Burgos Morgade Cortizo

    Analista de Sistemas Pleno da PETROBRAS S.A., Msc. em Redes de Computadores e entusiasta

    do Java h quase 10 anos.

    De que se trata o artigo:

    Uso da biblioteca Beans Binding para implementao do padro Presentation Model em

    interfaces Swing para aplicaes Java e como o uso desta tcnica permite construir interfaces

    desktop para sistemas Java de forma simples e produtiva.

    Para que serve:

    Fornecer um meio para implementar clientes desktop ricos capazes de intercambiar dados

    automaticamente entre a interface e o modelo de negcio. Permite tambm controlar o

    comportamento de uma tela apenas trabalhando com um modelo de apresentao simples e

    reutilizvel, sem a necessidade de manipulao direta de componentes grficos.

    Em que situao o tema til:

    Ao analisar as alternativas de interfaces para clientes ricos de sistemas corporativos, pois

    importante considerar os benefcios da utilizao de interfaces Swing e as tecnologias que

    facilitam o desenvolvimento e implantao como o Beans Binding e o Java Webstart.

    Swing + Beans Binding:

    O binding (ou vinculao) de propriedades de objetos simples a propriedades de componentes

    grficos do Swing permite construir interfaces que trocam dados automaticamente entre a

    interface grfica e as entidades de um sistema. Tambm permite implementar de forma simples

    o padro Presentation Model, atravs do qual possvel controlar o comportamento das telas

    apenas trabalhando com um modelo de apresentao simples e reutilizvel, sem a

    necessidade de manipulao direta de componentes grficos.

    Este artigo apresenta a API de Beans Binding e como seu uso integrado com o Swing GUI

    Builder do NetBeans 6.5 (anteriormente conhecido como Matisse). Veremos como a API de

  • binding consegue sincronizar as propriedades de diferentes objetos e particularmente de

    componentes grficos do Swing. Finalmente, ser explicado como esta API pode ser usada

    como ferramenta facilitadora para implementao do padro de projeto chamado de

    Presentation Model.

    Java no desktop?Esta pergunta talvez ainda seja feita pelos desenvolvedores mais experientes. Na realidade,

    quem conviveu com os primeiros anos do Java tem todo o direito de questionar a viabilidade

    deste tipo de aplicao. O Swing trouxe componentes grficos elegantes baseados num

    modelo MVC, mas no to simples de trabalhar.

    Os gerenciadores de layouts, apesar de eficientes, no tinham a agilidade de ambientes

    WYSIWYG para prototipao rpida de telas.

    Porm, com o tempo a situao mudou bastante. A plataforma e as IDEs evoluram. Hoje, com

    as novas ferramentas e com o Java Webstart para distribuio automatizada, uma interface

    desktop para aplicaes corporativas uma alternativa s interfaces Web no apenas vivel,

    mas tambm muito produtiva e eficiente.

    O recente lanamento JavaFX o ltimo avano nesta escalada, mas ainda uma tecnologia

    em processo de amadurecimento que aos poucos vai ganhar suporte mais completo das IDEs.

    Uma das features interessantes da JavaFX foi o suporte nativo ao binding de propriedades (ou

    vinculao, em traduo livre).

    Porm, fora da JavaFX tambm possvel implementar a vinculao de propriedades entre

    dois objetos, e esta uma das ferramentas mais interessantes para acelerar o

    desenvolvimento de aplicaes desktop.

    Neste artigo vamos demonstrar como a biblioteca BeansBinding implementa esse processo e

    como utiliz-lo de forma produtiva atravs do suporte oferecido pelo NetBeans 6.5.

    Beans Binding Manter duas propriedades de dois objetos em sincronia mais complicado do que parece,

    principalmente se isso deve ser encapsulado em uma API com baixo nvel de intruso no

    cdigo de negcio.

    De forma rpida e crua, possvel vincular a propriedade de dois objetos como na forma

    usada na Listagem 1. Aps este trecho de cdigo, o texto Z impresso. Enquanto o binding

    estiver ativo, qualquer alterao na propriedade nome do objeto c1 automaticamente

    refletida em c2 (e vice-versa). A API Beans Binding baseada nas especificaes de

    propriedades JavaBeans e na capacidade de instalar escutadores de estados nos objetos a

    serem sincronizados.

    Listagem 1. Listagem 1. Uso manual do BeansBinding

    Contato c1 = new Contato();

    Contato c2 = new Contato();

    Binding binding = Bindings.bind(UpdateStrategy.READ_WRITE, c1,

    BeanPropery.create("nome"), c2, BeanProperty.create("nome"));

    Binding.bind();

    c1.setNome("Z");

    System.out.println(c2.getNome());

    Porm, esta automao exige que a classe Contato respeite o contrato de definio de

  • propriedades e publicao de eventos da especificao JavaBeans. De forma mais objetiva, o

    Beans Binding exige que a classe implemente os padres setters e getters de nomeao para

    encapsular propriedades, e a disponibilizao dos mtodos addPropertyChangeListener() e

    removePropertyChangeListener(). Essas exigncias podem ser observadas na Listagem 2.

    O principal a se notar neste cdigo o uso do PropertyChangeSupport, que uma classe

    utilitria do pacote JavaBeans responsvel por gerenciar e notificar os escutadores de

    mudana de propriedade (implementadores da interface PropertyChangeListener).

    A classe Contrato deve ter a responsabilidade extra de notificar todas as mudanas de valores

    de suas propriedades para que o Beans Binding saiba os momentos em que a sincronizao

    necessria (usando o mtodo firePropertyChange() do propertyChangeSupport). Alguns

    podem achar que h bastante cdigo intruso nesta classe, mas na verdade ela est apenas

    implementando uma das primeiras e mais recomendas especificaes do Java (ver quadro

    POJO: Ser ou no ser... Eis a questo).

    Listagem 2. Classe Contato

    package org.morgade.exemplo.entity;

    import java.beans.PropertyChangeListener;

    import java.beans.PropertyChangeSupport;

    public class Contato {

    private final Property

    ChangeSupport propertyChangeSupport =

    new PropertyChangeSupport(this);

    private String nome;

    private String telefone;

    private Empresa empresa;

    public void setTelefone(String telefone) {

    String oldTelefone = this.telefone;

    this.telefone = telefone;

    if (this.telefone != null && !

    this.telefone.startsWith("0-XX-"))

    this.telefone = "0-XX-" + this.telefone;

    propertyChangeSupport.

    firePropertyChange("telefone",

    oldTelefone, telefone);

    }

    public void setNome(String nome) {

    String oldNome = this.nome;

    this.nome = nome;

    propertyChangeSupport.fire

    PropertyChange("nome", oldNome, nome);

    }

    public void setEmpresa(Empresa empresa) {

    Empresa oldEmpresa = this.empresa;

  • boolean oldPessoal = isPessoal();

    this.empresa = empresa;

    propertyChangeSupport.fire

    PropertyChange("razaoSocial",

    oldEmpresa, empresa);

    propertyChangeSupport.

    firePropertyChange

    ("pessoal", oldPessoal, isPessoal());

    }

    public String getTelefone() {

    return telefone;

    }

    public String getNome() {

    return nome;

    }

    public Empresa getEmpresa() {

    return empresa;

    }

    public boolean isPessoal() {

    return empresa == null;

    }

    public void addPropertyChangeListener

    (PropertyChangeListener listener) {

    propertyChangeSupport.

    addPropertyChangeListener(listener);

    }

    public void removePropertyChangeListener

    (PropertyChangeListener listener) {

    propertyChangeSupport.

    removePropertyChangeListener(listener);

    }

    }

    Assim, na Listagem 1, a chamada Bindings.createAutoBinding() registra

    PropertyChangeListeners nos objetos c1 e c2, para que cada mudana detectada na

    propriedade nome seja notificada para posterior sincronizao dos valores nos dois objetos.

    Cada binding tem uma origem (o objeto c1) e um destino (o objeto c2). A enum

    UpdateStrategy, como sugere o nome, define como se aplica a sincronizao:

    UpdateStrategy.READ_WRITE: Mudanas na propriedade do objeto fonte so aplicadas na

    propriedade do objeto destino e vice-versa;

    UpdateStrategy.READ: Mudanas na propriedade do objeto fonte so aplicadas na

    propriedade no objeto destino, mas mudanas na propriedade do objeto destino no so

    aplicadas no objeto origem;

    UpdateStrategy.READ_ONCE: O estado da propriedade do objeto origem aplicado na

    propriedade do objeto destino apenas no momento da chamada do mtodo bind().

  • Novamente na Listagem 1, observe como a definio da propriedade a ser vinculada

    especificada no binding (3 e 5 parmetros). O Beans Binding define a classe abstrata

    Property para unificar a forma de acesso a propriedades. As seguintes implementaes desta

    classe so usadas:

    BeanProperty: Permite definir as propriedades atravs de uma String que suporta vrios nveis

    de caminhos. Seria possvel, por exemplo, especificar a propriedade endereco.rua, na classe

    Contato;

    ELProperty: Permite definir propriedades usando a especificao de Expression Language do

    Java. possvel, por exemplo, usar a expresso ${not empty nome} para definir uma

    propriedade da classe Contato que pode ser vinculada a uma propriedade boolean de outro

    objeto.

    Dessa forma, o Beans Binding usa as definies de propriedade para propagar as mudanas

    entre os objetos, controlando problemas de recursividade e possveis ciclos de vinculao e

    gerenciando caches de propriedade para otimizar a performance.

    A questo que como sempre estamos pensando em sistemas WEB, no nos preocupamos

    em implementar a publicao de mudanas de propriedades (j que na WEB quase sempre as

    propriedades dos objetos so setadas em seqncia durante alguma fase da resposta

    requisio). Assim, defina detalhadamente seu conceito de POJO antes de responder a

    questo deste quadro.

    POJO: Ser ou no ser... Eis a questoO uso dos padres do PropertyChangeSupport nas classes de negcio nos leva a uma

    questo controversa: Assim minhas classes no deixaro de ser POJOs ?. O problema da

    necessidade do PropertyChangeSupport nas classes na verdade a falta de suporte nativo

    do Java para a publicao de eventos de mudanas de propriedades.

    Qualquer metodologia de binding s possvel com o uso de escutadores de propriedades

    para disparar as sincronizaes. O importante observar que as classes de apoio

    publicao de propriedades usadas no cdigo no pertencem API de binding e sim ao

    pacote JavaBeans (que um pacote padro no Java para publicao de propriedades, e est

    em qualquer JRE. O prprio NetBeans tem a opo de gerar setters com PropertyChange

    independente de usar bindings).

    No fim das contas, definir o que um POJO quase uma questo filosfica. Ser POJO ou no

    ser POJO neste caso depende do significado exato que voc d a este termo. O fato que a

    maioria dos chamados POJOs que vemos por a so JavaBeans (objetos Java simples sem

    dependncias externas, com construtores sem parmetros e mtodos setters e getters

    representando propriedades).

    at possvel esconder o cdigo do PropertyChangeSupport usando AOP ou implementando

    proxies dinmicos, mas nem sempre a publicao da mudana algo que deve ser

    automatizado, pois faz parte das regras internas contidas no encapsulamento do

    comportamento da classe.

    Swing Binding e o padro PresentationModelO Beans Binding mostra seu real poder ao ser combinado com os componentes do Swing.

    possvel por exemplo fazer o binding da propriedade nome do nosso objeto Contato

  • propriedade text de um JTextField e fazer com que o nome seja atualizado automaticamente

    medida que o usurio digita na tela. Na mesma tela possvel tambm vincular a expresso

    como ${not empty nome} propriedade enabled de um boto, que faz com que o mesmo

    habilite ou desabilite automaticamente quando o campo de texto est vazio ou preenchido.

    Podemos vincular o contedo de uma JTable a uma java.util.List e ver a tabela se atualizar

    automaticamente ao fazer operaes simples de adio e remoo na lista. O Beans Binding

    disponibiliza um pacote chamado Swing Binding, com adaptadores capazes de implementar

    propriedades sintticas nos componente grficos que so usados nos bindings (como as

    propriedades elements e selectedElements do JTable e JComboBox). Toda a complexidade

    de implementao dos modelos de dados para os componentes fica escondida sob o Swing

    Binding.

    Essas facilidades obtidas com o Swing Binding o tornam uma ferramenta excelente para

    aplicar o padro de projeto chamado Presentation Model nas telas de uma aplicao. De

    maneira geral, o padro Presentation Model prope uma forma de controlar o estado e o

    comportamento de uma interface grfica com usurio (GUI) apenas manipulando um modelo

    de classes de negcio, e no atravs de componentes grficos. Um mecanismo de binding

    entre componentes e objetos de negcio essencial para o funcionamento do Presentation

    Model. Na seo a seguir veremos como usar os recursos do Netbeans 6.5 para implementar

    uma tela Swing usando o padro Presentation Model atravs de Beans Binding.

    Swing Binding no NetBeans 6.5Nosso projeto de exemplo ser a clssica agenda de contatos, que usa as classes Contato e

    Empresa, presentes nas Listagens 2 e 3. A tela foi projetada no NetBeans GUI Builder e pode

    ser vista na Figura 1.

    [abrir imagem em janela]

    Figura 1. Projeto da tela no NetBeans GUI Builder

    Listagem 3. Classe Empresa

  • package org.morgade.exemplo.entity;

    import java.beans.PropertyChangeListener;

    import java.beans.PropertyChangeSupport;

    public class Empresa {

    private PropertyChangeSupport

    propertyChangeSupport =

    new PropertyChangeSupport(this);

    private String razaoSocial;

    public Empresa(String razaoSocial) {

    this.razaoSocial = razaoSocial;

    }

    public String getRazaoSocial() {

    return razaoSocial;

    }

    public void setRazaoSocial(String razaoSocial) {

    String oldRazaoSocial = this.razaoSocial;

    this.razaoSocial = razaoSocial;

    propertyChangeSupport.

    firePropertyChange

    "razaoSocial", oldRazaoSocial, razaoSocial);

    }

    @Override public String toString() {

    return razaoSocial;

    }

    public void addPropertyChangeListener

    (PropertyChangeListener listener) {

    propertyChangeSupport.

    addPropertyChangeListener(listener);

    }

    public void removePropertyChangeListener

    (PropertyChangeListener listener) {

    propertyChangeSupport.

    removePropertyChangeListener(listener);

    }

    }

    Para criar um presentation model que represente esta tela precisamos pensar em todos os

    dados necessrios para controlar o estado dela em forma de classes de negcio, classes

    utilitrias ou tipos primitivos. Este um exerccio comum ao usar este tipo de abordagem, e

    permite partir facilmente de uma tela projetada como prottipo para uma tela funcional.

    Observe o nosso presentation model na Listagem 4. O contedo da tabela representado

    pela propriedade listaDeContatos. Precisamos tambm representar um elemento de estado

    importante que o elemento selecionado na tabela. Este papel da propriedade

    contatoSelecionado. O valor dos campos nome, telefone e empresa devem sempre exibir os

    dados do contato selecionado na tabela. Assim, o presentation model no precisa de

  • propriedades especficas para estes campos.

    Finalmente, o JComboBox de empresas deve ser preenchido com uma lista, independente do

    contato selecionado. Para isso usamos a propriedade listaDeEmpresas no presentation model.

    Listagem 4. Classe AgendaPresentationModel

    package org.morgade.exemplo.presentation.model;

    import java.beans.PropertyChangeListener;

    import java.beans.PropertyChangeSupport;

    import java.util.ArrayList;

    import java.util.List;

    import org.jdesktop.observablecollections.

    ObservableCollections;

    import org.morgade.exemplo.entity.Contato;

    import org.morgade.exemplo.entity.Empresa;

    public class AgendaPresentationModel {

    private PropertyChangeSupport property

    ChangeSupport =

    new PropertyChangeSupport(this);

    private List listaDeEmpresas;

    private List listaDeContatos;

    private Contato contatoSelecionado;

    public AgendaPresentationModel() {

    listaDeContatos = ObservableCollections.

    observableList(new ArrayList());

    listaDeEmpresas = new ArrayList();

    listaDeEmpresas.add(null);

    listaDeEmpresas.add

    (new Empresa("Empresa A"));

    listaDeEmpresas.add

    (new Empresa("Empresa B"));

    listaDeEmpresas.add

    (new Empresa("Empresa C"));

    listaDeEmpresas.add

    (new Empresa("Empresa D"));

    }

    public void novoContato() {

    Contato c = new Contato();

    c.setNome("Novo contato");

    c.setTelefone("222-2222");

    listaDeContatos.add(c);

    }

    public void excluirContato() {

    listaDeContatos.remove

    (contatoSelecionado);

    }

    public List getListaDeContatos() {

    return listaDeContatos;

  • }

    public Contato getContatoSelecionado() {

    return contatoSelecionado;

    }

    public List getListaDeEmpresas() {

    return listaDeEmpresas;

    }

    public void setContatoSelecionado

    (Contato contatoSelecionado) {

    Contato oldContatoSelecionado =

    this.contatoSelecionado;

    this.contatoSelecionado =

    contatoSelecionado;

    propertyChangeSupport.firePropertyChange

    ("contatoSelecionado", oldContatoSelecionado,

    contatoSelecionado);

    }

    public void addPropertyChangeListener

    (PropertyChangeListener listener) {

    propertyChangeSupport.

    addPropertyChangeListener(listener);

    }

    public void removePropertyChangeListener

    (PropertyChangeListener listener) {

    propertyChangeSupport.removeProperty

    ChangeListener(listener);

    }

    }

    Agora que temos a tela e o presentation model correspondente, precisamos fazer a cola

    entre os dois. No nosso exemplo, o presentation model ser uma propriedade de nossa tela

    (apesar do padro de projeto tambm permitir a associao no sentido inverso). Observe na

    Listagem 5 que o presentation model declarado no cdigo fonte do JFrame, instanciado

    antes da inicializao dos componentes, e disponibilizado para acesso atravs de um mtodo

    getModel(). O presentation model deve ser instanciado antes da inicializao dos

    componentes pois o estado inicial da interface j deve estar disponvel quando a tela for

    aberta. Isso tudo permite usar os editores de binding do NetBeans e nos permite configurar a

    ligao da tela com os objetos de negcio sem precisar escrever nenhuma linha de cdigo.

    Listagem 5. Parte do cdigo da classe AgendaFrame

    package org.morgade.exemplo.presentation.gui;

    import org.morgade.exemplo.

    presentation.model.AgendaPresentationModel;

    public class AgendaFrame

  • extends javax.swing.JFrame {

    private AgendaPresentationModel model;

    public AgendaFrame() {

    model = new AgendaPresentationModel();

    initComponents();

    }

    public AgendaPresentationModel getModel() {

    return model;

    }

    /* ... Cdigo gerado de inicializao e binding de componentes (oculto) ... */

    private void btNovoActionPerformed(java.awt.event.ActionEvent evt)

    {

    model.novoContato();

    }

    private void btApagarActionPerformed

    (java.awt.event.ActionEvent evt) {

    model.excluirContato();

    }

    public static void main(String args[]) {

    java.awt.EventQueue.invokeLater(new Runnable() {

    public void run() {

    new AgendaFrame().setVisible(true);

    }

    });

    }

    }

    Editar o binding de um componente no NetBeans semelhante a editar uma propriedade. Ao

    clicar em um componente, observe que o editor de propriedades tem uma aba chamada

    Binding (ou Vinculao se o seu NetBeans estiver em portugus). Ao clicar no JTextField de

    nome, e depois no boto de edio do binding da propriedade text, a tela de edio de binding

    exibida (Figura 2).

    No campo Binding Source so listados todos os componentes da tela. Como nosso

    presentation model uma propriedade da tela, selecionamos o componente raiz (por padro

    com o nome de Form). Ao selecionar o Binding Source, o campo Binding Expression

    carregado com a rvore de propriedades do mesmo. Observe na Figura 2 que ao selecionar

    uma propriedade na rvore, uma expresso automaticamente montada para compor o

    binding do componente.

    A rvore somente um assistente, uma vez que a expresso pode ser digitada manualmente.

    No caso do componente textNome, usamos a expresso ${model.contatoSelecionado.nome}

    para fazer com que o campo sempre exiba o nome do contato selecionado na tabela.

    [abrir imagem em janela]

  • Figura 2. de binding da propriedade text do JTextField que mostra o nome

    Na aba Advanced do editor de binding existem outras configuraes importantes como

    conversores de tipos, validaes e valores padro. Neste artigo no detalharemos estas

    configuraes, mas importante experiment-las para customizar a tela para modelos mais

    complexos.

    O editor de binding mais complexo o do JTable e ele deve ser acessado clicando com o

    boto direito na tabela e selecionado Table Contents .... A aba Table Model semelhante s

    demais, bastando selecionar a opo Bound (Figura 3). Usaremos a expresso

    ${model.listaDeContatos} para definir a propriedade que contm a lista de elementos da

    tabela. Na aba Columns podemos definir um conjunto de colunas com sub-expresses sobre o

    contexto de um elemento da lista original e assim definir o seu contedo (Figura 4). Clique no

    boto Insert e configure expresses para as propriedades nome e telefone.

    Outra propriedade importante para binding do JTable a selectedElement. Ela pode ser

    acessada tambm na aba Binding do editor de propriedades padro. Ela deve ter a expresso

    ${model.contatoSelecionado} para que o model seja atualizado automaticamente sempre que

    o usurio selecionar um novo elemento na tabela.

    [abrir imagem em janela]

  • Figura 3. Table Model do editor de binding da propriedade elements do JTable

    [abrir imagem em janela]

    Figura 4. Aba Columns do editor de binding da propriedade elements do JTable

    A Tabela 1 faz um resumo da configurao de binding de cada elemento da tela. Observe que

    o JComboBox tambm precisa de configurao da propriedade elements e da

    selectedElement. O combo usar o mtodo toString() da classe Empresa para exibir os objetos

    (no caso do componente JList, o binding aceita uma expresso especfica para exibio de

    cada objeto da lista).

  • [abrir imagem em janela]

    Tabela 1. Configurao de binding de cada elemento da tela

    Pedras no caminhoNem tudo perfeito na histria do Beans Binding. preciso ter conscincia de que o uso da

    Expression Language para definio das propriedades no binding trazem um pouco mais de

    dificuldade em possveis operaes de refactoring automatizadas das propriedades, uma vez

    que as ferramentas ainda no esto preparadas para fazer substituies automatizadas nas

    expresses. Porm, este o mesmo tipo de problema existente em queries HQL e

    configuraes de componentes JSF, e dependem de novas ferramentas de suporte para

    serem resolvidos.

    Outro problema difcil de compreender a inatividade da especificao JSR-295. Enquanto o

    NetBeans j prov um suporte de timo nvel ao Beans Binding (que a implementao de

    referncia da JSR), o time que comanda a especificao e a implementao est parado h

    um ano. Mas a comunidade que usa a API no deixa barato e uma nova implementao

    baseada na especificao comeou sua atividade com o sugestivo nome de Better Beans

    Binding (ver Links).

    Outra configurao interessante a do componente checkBoxPessoal. O binding da sua

    propriedade selected simples, mas observe que a propriedade pessoal da classe Contato

    sinttica e de somente leitura (Listagem 2). Um contato considerado pessoal se ele no

    tem empresa associada. Observe como essa regra faz com que o setter da propriedade

    empresa precise tambm notificar uma possvel mudana da propriedade pessoal. Com isso,

    se o usurio selecionar uma empresa para um contato, o JCheckBox automaticamente.

    Finalmente, observe que os componentes de entrada de dados do contato, assim como o

    boto Apagar, tm um binding configurado da propriedade enabled para a expresso ${not

    empty model.contatoSelecionado}. Isso faz com que os campos e o boto s estejam

    habilitados para edio/excluso quando existir alguma linha selecionada na tabela.

    Com todas estas ligaes aplicadas, a tela est pronta para espelhar os estados definidos no

    presentation model. O estado inicial da tela ser determinado pelo construtor do presentation

    model. Neste construtor (Listagem 4), importante perceber a forma como as listas so

    inicializadas. Observe que a lista de contatos inicializada com a criao de uma lista

    observvel atravs da classe ObservableCollections, disponvel na API do Beans Binding. Com

    ela, podemos criar listas capazes de notificar alteraes de estado e assim possibilitar a

  • sincronizao dela com componentes como o JTable. Assim, cada vez que adicionarmos um

    objeto nesta lista, a tabela em nossa tela ganhar automaticamente uma nova linha. A lista de

    empresas no precisa ser observvel em nossa tela, uma vez que tratada como uma lista

    esttica.

    A ltima coisa necessria para configurar na nossa tela so as aes dos botes. Para

    simplificar este exemplo, clicamos duas vezes em cada boto para o NetBeans criar as aes

    automaticamente. Usando os conceitos do presentation model, as aes das telas devem ser

    extremamente simples. No nosso exemplo elas apenas delegam as chamadas paras os

    mtodos novoContato() e excluirContato() do presentation model.

    O mtodo novoContato() instancia um novo objeto Contato, seta alguns valores padro e o

    adiciona na lista de contatos. Assim, cada vez que esse boto for clicado, a tabela ganha uma

    nova linha.

    O mtodo excluirContato() simplesmente exclui da lista o objeto representado pela propriedade

    contatoSelecionado. Assim, quando esse boto clicado, a linha selecionada desaparece da

    tabela.

    Observe como a tela fica dinmica e interativa sem a necessidade de sujar as mos com

    muito cdigo de Swing. A classe do Presentation Model no tem nenhuma dependncia do

    pacote javax.swing e pode at mesmo ser usada numa verso em JSF desta mesma tela sem

    qualquer alterao. O binding cria efeitos interessantes como observar o dado na tabela ser

    alterado medida que se digita nas caixas de texto. As prprias clulas da tabela so

    editveis, refletindo as atualizaes nos campos de texto.

    Observe tambm como o binding consegue detectar mudanas como da propriedade telefone

    no Contato. Na Listagem 2 vemos que o setter desta propriedade processa o valor textual,

    adicionando um prefixo "0-XX-" que exibido automaticamente na tela aps a edio.

    sempre interessante abrir o cdigo gerado pelo NetBeans e tentar compreender como ele

    transforma nossas configuraes em chamadas para a API de Beans Binding. Afinal, temos

    que ter uma compreenso mnima de como as coisas funcionam para saber onde mexer

    quando algum problema acontecer.

    Finalmente, imagine o trabalho necessrio para fazer uma tela com este mesmo

    comportamento trabalhando sem Binding, ou usando solues Web do tipo AJAX. Isso um

    assunto para artigos futuros, mas imagine tambm como esse tipo de modelo se adapta ao

    uso de tecnologias como Hibernate. Podemos fazer uma query HQL que retorna um List de

    Contatos e fazer um binding diretamente do resultado desta consulta para um JTable. O

    usurio pode editar estes objetos e numa nica linha de cdigo podemos fazer um merge das

    mudanas e atualizar a base de dados. O presentation model normalmente o ponto de

    integrao com a camada de negcio do sistema, possuindo por exemplo, referncias a

    objetos de servios locais ou remotos.

    Concluses Java no desktop? Sim! Apesar da barreira tecnolgica certamente ser mais fcil de superar

    do que a psicolgica (aquela voz na cabea de todo arquiteto que parece sempre dizer a

    mesma coisa independente do cenrio: O sistema deve ter uma interface Web).

    Esse pequeno exemplo demonstra como o uso da API Beans Binding pode tornar o

    desenvolvimento de aplicaes de interface desktop uma tarefa mais simples e produtiva.

  • Apesar de no estar livre de problemas (ver quadro Pedras no caminho), esta uma forma

    gil de criar interfaces desktop funcionais e interativas. E mesmo que voc no pretenda usar

    este tipo de abordagem, importante entender os conceitos que envolvem o binding de

    propriedades, pois tecnologias como a JavaFX mostram que o futuro aponta para isso.