Esse artigo faz parte da revista Java Magazine edição 60. Clique aqui para ler todos os artigos desta edição

AN style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: red; FONT-FAMILY: Verdana; moz-background-clip: -moz-initial; moz-background-origin: -moz-initial; moz-background-inline-policy: -moz-initial">

:p>

Sincronizando propriedades entre objetos

Aprenda sobre o BeansBinding e as facilidades do NetBeans 6

De que se trata o artigo:

Uso dos componentes da especificação BeansBinding para sincronizar propriedades de objetos de maneira mais fácil e produtiva, minimizando o típico uso de listeners. Neste artigo foi mostrado como usar as classes dessa especificação sem o suporte de uma IDE e, ao final, foi mostrado como usar o Netbeans para apoiar o uso dessas classes.

 

Para que serve:

Fornecer um meio de sincronizar propriedades de objetos distintos, de forma automática e produtiva, permitindo que uma ferramenta IDE apóie o seu uso para facilitar a codificação.

 

Em que situação o tema é útil:

Simplificar a codificação quando é necessário fazer a informação transitar de um objeto para outro, entre suas propriedades, de forma sincronizada – quando a informação é modificado em um dos lados, o outro é atualizado automaticamente. Com o suporte de IDEs Java, como o NetBeans, o uso de BeansBinding pode simplificar muito a construção de aplicações desktop.

 

BeansBinding:

O principal objetivo da JSR-295 é estabelecer um padrão para manter em sincronia as propriedades de dois objetos. O uso dos componentes dessa especificação simplifica a codificação necessária para manter as propriedades de objetos distintos trocando informações entre si, como pode ser visto nas Listagens 1 e 2. Notificações automáticas para modificações em atributos de nossas classes podem ser incluídas usando o PropertyChangeSupport, conforme as Listagens 3 e 4. Essa especificação também traz uma maneira de criarmos o controle do ciclo de vida do binding (Listagem 5), conversores e validadores. Propriedades especiais (Tabela 1) dão suporte a componentes Swing mais complexos (JList,  JTable e JSlider, por exemplo), como mostra a Listagem 6.

Apresentados os fundamentos da JSR-295, mostraremos as facilidades encontradas no NetBeans 6.1, que apresenta recursos poderosos combinando BeansBinding com Swing Aplication Framework (JSR-296) e Java Persistence API. Você aprenderá a construir aplicações desktop com produtividade e pouca codificação.

 

Em geral, a construção de aplicações desktop em Java não costuma ser trivial. Programadores Visual Basic ou Delphi, acostumados com o arrastar e soltar dessas ferramentas, escrevendo pouco código em função do uso intenso de propriedades em tempo de projeto, constroem rapidamente aplicações relativamente complexas. Ao se depararem com o Java, têm alguma dificuldade em migrar. Se até uma simples janela de mensagens parece ser complicada à primeira vista, leva algum tempo até entender e usar bem os Gerenciadores de Layout e o Swing.

Em aplicações desktop mais elaboradas é muito comum a manutenção de banco de dados através das telas da aplicação. Com a popularização do JavaBeans e dos frameworks de mapeamento objeto relacional (EJB3/JPA, Hibernate, TopLink), principalmente no desenvolvimento web, boa parte do trabalho é associar os componentes visuais com os JavaBeans. Outro desafio é saber como amarrar os componentes visuais com os dados, mantendo uma boa separação em camadas.

Nos últimos anos a Sun vem recuperando o prejuízo. O GroupLayout, incorporado ao Java SE 6 e conhecido no NetBeans como Matisse, trouxe finalmente uma construção simples e realmente multiplataforma de interfaces gráficas. O próximo passo seria então atacar a amarração de dados e o gerenciamento geral de uma aplicação desktop. A JSR-295 – BeansBinding – veio para ajudar a atender essas necessidades e será o tema principal desse artigo. Como exemplo utilizaremos uma aplicação hipotética de Agenda pessoal. Veremos as facilidades disponíveis no NetBeans, sem deixar de comentar um pouco sobre como as coisas acontecem “nos bastidores”.

A JSR-295

O principal objetivo da JSR-295 é estabelecer um padrão para manter em sincronia as propriedades de dois objetos. Além de objetos no padrão JavaBean, suporta  objetos Maps e Lists. Digamos que precisamos criar um painel apenas com JCheckBox que, se marcado, deve habilitar um JTextField (Figura 1).

 

Figura 1. Seleção de JCheckBox com habilitação de JTextField com BeansBinding

Pelo modo tradicional, esse seria o código necessário:

 

jCheckBox1.addActionListener(new java.awt.event.ActionListener() {

  public void actionPerformed(java.awt.event.ActionEvent evt) {

    jTextField1.setEnabled(jCheckBox1.isSelected());

  }

});

 

Usando o BeansBinding, teríamos:

 

Binding b = Bindings.createAutoBinding(

  UpdateStrategy.READ, // Estratégia de mudança das propriedades

  jCheckBox1, BeanProperty.create("selected"),  // Objeto e propriedade origem

  jTextField1, BeanProperty.create("enabled")); // Objeto e propriedade destino

b.bind();

 

Comparando as duas formas, você pode pensar que não houve economia de código. Nesse caso, isso pode até ser verdade, mas há vantagens em usar o BeansBinding que podem ser percebidas entendendo melhor o exemplo. Uma delas é de que não precisamos nos preocupar com os diferentes tipos de Listener presentes no Swing, apenas conhecer as propriedades que serão relacionadas. Simplifica muito o aprendizado de codificação de um aplicativo em Java, pois uma das grandes dificuldades dos iniciantes é justamente entender como funcionam os Listeners. Outras vantagens serão percebidas mais adiante.

Para que o exemplo funcione, foi preciso informar o objeto e propriedades de origem e destino. As propriedades são definidas usando BeanProperty.create(), fornecendo o nome da propriedade. Opcionalmente – mas altamente recomendável – devemos informar a estratégia (chamada Update Mode na JSR) usada para sincronizar as propriedades. Aqui usamos o UpdateStrategy.READ, que mantém o objeto destino sincronizado com o objeto origem. Fizemos a ligação entre as propriedades usando a classe abstrata Binding. Criamos instâncias concretas usando uma fábrica para objetos Binding através de Bindings.createAutoBinding(). O objeto AutoBinding criado irá manter a sincronia entre as propriedades usando uma estratégia de atualização.

As possíveis estratégias de atualização definidas nessa JSR são:

·         Always sync (read/write) ou UpdateStrategy.READ_WRITE: informa que quando uma mudança for feita na origem ou no destino, o outro lado é atualizado. Isso poderia ser útil, por exemplo, para associar um JTextField com um JSlider para manter ambos os controles em sincronia;

·         Only read from source (read only) ou UpdateStrategy.READ: informa que as mudanças que forem feitas na origem são atualizadas no destino, mas as mudanças feitas no destino não são atualizadas na origem. Exemplificamos essa estratégia nesse artigo;

·         Read from source once (read once) ou UpdateStrategy.READ_ONCE: o destino só é atualizado quando ambos, destino e origem, são colocados em memória, ou seja, apenas uma vez. Poderíamos usar essa estratégia, por exemplo, para sincronizar objetos que não gostaríamos que mudassem com a interação com o usuário.

Acessando propriedades

A classe abstrata Property define um modo uniforme para acessar valores de uma propriedade que siga o padrão JavaBean. Ela possui poucos métodos que são bastante auto-explicativos, como getValue(Object obj), setValue(Object obj, Object value), isReadable(Object obj), isWriteable(Object obj) e outros. As duas classes descendentes que nos interessam são BeanProperty e ...

Quer ler esse conteúdo completo? Tenha acesso completo