Palestra do Conexao Java no ar

novembro 20th, 2006

Como prometido, coloquei a palestra do Conexão Java na seção de Palestras do blog. Pretendo postar o demo em breve também.

Review do Conexao Java 2006

novembro 20th, 2006

Fui só no segundo dia do evento e acabei chegando só 10:20. A localização do evento foi muito melhor este ano, principalmente porque entendo da Vila Olímpia :-)

O primeiro conhecido – virtualmente, nunca havia encontrado em pessoa – que avistei foi o Rubem Azenha, do Mentawai, que me explicou onde retirar as credenciais. Aí, uma surpresa: o Anderson, que era da Sucesu, estava coordenando o evento dos caras. Peguei minha credencial e o kit do evento e dei uma entrada no auditório pra ver como era o ambiente e arrumar minhas coisas. Era a palestra da IBM sobre SOA. Aparentemente ele não estava vendendo o WebSphere e sim explicando como adotar SOA inicialmente numa empresa, o que eu achei muito bom.

Quando sai, conversei um pouco com o Rubem e ele ficou curioso sobre como o genesis conseguia implementar a remotabilidade transparente, que permite executar métodos de POJOs criados diretamente com new em um servidor Java EE ou em modo local sem exigir qualquer mudança no código fonte. Acabamos devaneando um pouco sobre a história do genesis, coisas que sinto falta no Spring e outros assuntos diversos. Nesse meio tempo, falei um pouco com o Eduardo Bregaida, mal reconheci o Senger sem sua extensa cabeleira, vi a Yara com a futura instrutora da Globalcode (a filha dos dois) e dei oi pro Rafael Steil e pro Diego Plentz (desculpa não ter conversado com vocês).

Finalmente – o evento estava atrasado – o Anderson disse que podia ir pra acertar o ambiente e comecei minha palestras as 11:50. Como combinado, falei sobre desenvolvimento desktop, apresentando as opções de tecnologias de UI, ferramentas de design visual, binding, distribuição e integração com o backend. Essa foi a parte chata, porque divertido mesmo foi quando me arrisquei e comecei a fazer um CRUD do zero em plena palestra. Desenhei uma tela com uma tabela listando algumas propriedades de um bean, um botão de Novo, Editar e Excluir e comecei a fazer tantas coisas funcionar quanto possível. FIz a listagem, a seleção funcionar, a lógica de habilitação dos botões Editar e Excluir, a exclusão em si e ainda acrescentei a pergunta de “Deseja realmente excluir este usuário?” antes da exclusão, a pedido da platéia. O mais divertido é que criei um usuário pro Rubem que apaguei diversas vezes durante o demo. :-P Ainda mostrei a aplicação rodando localmente e remotamente com o mesmo código e mostrei um pouco de como funciona o Java WebStart. Deu pra mudar a percepção da galera sobre o desenvolvimento desktop e mostrar como a combinação Matisse + genesis é extremamente produtiva. A receptividade foi ótima e considero que foi minha melhor palestra até hoje. Se você assistiu a palestra e quiser deixar sua opinião, agradeço!

Depois da palestra, respondi algumas perguntas e fui almoçar com o Hideraldo, Renato Câmara e o Rodrigo Santos. Como tinha outro compromisso, tive que ir embora logo após o almoço e não pude conversar com o povo nem assistir outra palestra. Depois posto os slides da palestra e a demonstração.

PS: Sim, em breve escrevo sobre boas práticas de gerenciamento de releases com CVS… :-P

Resumo

novembro 16th, 2006

Bom, muito tempo sumido, muitas coisas acontecendo, então, lá vai:

  • A implementação das três grandes plataformas Java (ME, SE e EE) foi liberada como open-source sob a licença GPLv2 (com a Classpath exception pro SE e EE) nesta segunda, dia 13. Isso já havia sido cogitado no blog no dia 27/10. Quem lê o Blog do Mister M, sabe antes :-)
  • Vou apresentar uma palestra no Conexão Java 2006, Desenvolvendo aplicações desktop em Java: presente e futuro, no próximo sábado. Essa palestra vai apresentar, de forma prática, o leque de opções para desenvolvimento desktop que temos, um dos caminhos a seguir, e o que esperar das três JSRs relacionadas ao desktop que devem ser parte do Java 7. Já minha palestra no JustJava 2006, Desktop em minutos com genesis, Matisse, Java WebStart e JSR-296, vai ser bem mais focada em explorar essa arquitetura de desenvolvimento e em mostrar como ela vai evoluir com (e ajudar a evoluir a) JSR-296.
  • O tráfego na lista do genesis tem aumentado bastante. Bom saber disso :-) Pretendo fazer a release 3.0-EA5 ainda esse mês.
  • Se você é membro individual do JCP e está disposto a colaborar com uma JSR que vai resolver um dos problemas fundamentais do Java SE, mande um email. Vem coisa boa por aí…
  • Um dia desses, em alguma lista ou fórum brasileiro de Java, alguém perguntou sobre boas práticas de gerenciamento do CVS/Subversion para os diferentes ambientes e ciclos de release das aplicações. Eu já havia pensado em blogar sobre isso, pois já fiz de diversos jeitos e tenho alguns exemplos de quais estruturas adotar para cenários diferentes. Se mais alguém estiver interessado, deixe um comentário e talvez eu aborde esse tema no blog em breve.

Saiu o NetBeans 5.5

outubro 30th, 2006

Saiu o NetBeans 5.5. Comentários gerais:

  • Enterprise, Visual Web, Mobile e C++, disponíveis como packs, são demais. Gostei de nenhum deles ser incluído por default, o que tornava as primeiras distribuições enormes desnecessariamente.
  • A performance geral parece bem melhor.
  • Requer o JDK 5. Sinceramente, acho que podiam deixar pra migrar só no 6, até porque a maioria das APIs não usa generics nessa versão.
  • Jackpot, que agora uso já que estou rodando com JDK 5 mesmo, é bem legal. Pena que umas duas regras estão quebradas.
  • Deu uma travada aqui no meio da edição, uma vez só, do nada. Estranho…

Mais comentários em breve.

Bomba: Java vai ser GPLv2 ?!?!?!

outubro 27th, 2006

Pois é, notícias chocantes! Enquanto lia minhas feeds no Google Reader, vi um post no blog do Neal Gafter que continha um link para o projeto openjdk no java.net e com os headers da licença GPLv2. Aparentemente, alguém mandou ele remover o post, mas aqui está o contéudo armazenado no cache do meu leitor:

Oct 26, 2006 10:34 PM

Sun to open-source using GPLv2

from Neal Gafter’s blog
by Neal Gafter

It appears that Sun has started moving javac and HotSpot onto their respective java.net repositories. Apparently, you can browse the repository of the “Open JDK” project. And there, you can see that the license under which it is distributed is… GPL version 2! From https://openjdk.dev.java.net/source/browse/openjdk/hotspot/trunk/src/share/vm/c1/c1_CFGPrinter.cpp?rev=122&view=markup:

/*
 * Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 */

PS: Foi bom porque pelo menos tomei vergonha na cara e postei no blog ;-)

genesis 3.0-EA4: Suporte SWT e tutorial pelo Edgar

setembro 25th, 2006

Foi lançada alguns dias atrás a nova release do genesis, a 3.0-EA4. Uma das novidades é o binding SWT, expandindo o suporte desktop do framework, que já inclui Swing (desde a 3.0-EA3) e Thinlet.

O princípio do binding é o mesmo usado pelas outras tecnologias: você constrói sua interface normalmente, usando o Visual Editor do Eclipse ou codificando na mão mesmo, com o único requerimento de definir o nome dos seus componentes igual ao da propriedade ou ação com o que você deseja ligá-lo. No caso do SWT, usamos a propriedade data dos componentes como seu nome, mas isto pode ser mudado.

Escrever uma tela de login em SWT com o genesis é bem fácil. Primeiro definimos o form, que é o mesmo independente da tecnologia de GUI utilizada:


@Form
public class LoginForm {
   private String usuario;
   private String senha;

   public String getUsuario() {
      return usuario;
   }

   public void setUsuario(String usuario) {
      this.usuario = usuario;
   }

   public String getSenha() {
      return senha;
   }

   public void setSenha(String senha) {
      this.senha = senha;
   }

   @Action
   public void login() {
      System.out.println(usuario);
      System.out.println(senha);
   }

   @Action
   public void limpar() {
      setUsuario(null);
      setSenha(null);
   }
}

E depois o código que constrói a GUI SWT e faz a ligação com o form:


@ViewHandler
public class LoginSWTView {
   private Shell shell = null;
   private Composite composite = null;
   private Label labelUsuario = null;
   private Text usuario = null;
   private Label labelSenha = null;
   private Text senha = null;
   private Composite compositeBotoes = null;
   private Button limpar = null;
   private Button login = null;

   public LoginSWTView() {
      createShell();
      SWTBinder binder = new SWTBinder(shell, new LoginForm(), this);
      binder.bind();
   }

   private void createShell() {
      shell = new Shell();
      shell.setText("Login");
      createComposite();
      createCompositeBotoes();
      shell.setLayout(new GridLayout());

      shell.pack();
   }

   private void createComposite() {
      GridLayout gridLayout = new GridLayout();
      gridLayout.numColumns = 2;

      GridData gridData = new GridData();
      gridData.horizontalAlignment = GridData.FILL;
      gridData.verticalAlignment = GridData.FILL;

      composite = new Composite(shell, SWT.NONE);
      composite.setLayoutData(gridData);
      composite.setLayout(gridLayout);

      labelUsuario = new Label(composite, SWT.NONE);
      labelUsuario.setText("Usuário");

      usuario = new Text(composite, SWT.BORDER);
      usuario.setData("usuario");

      labelSenha = new Label(composite, SWT.NONE);
      labelSenha.setText("Senha");

      senha = new Text(composite, SWT.BORDER | SWT.PASSWORD);
      senha.setData("senha");
   }

   private void createCompositeBotoes() {
      RowLayout rowLayout = new RowLayout();
      rowLayout.fill = true;

      GridData gridData = new GridData();
      gridData.horizontalAlignment = GridData.END;
      gridData.verticalAlignment = GridData.FILL;

      compositeBotoes = new Composite(shell, SWT.NONE);
      compositeBotoes.setLayoutData(gridData);
      compositeBotoes.setLayout(rowLayout);

      limpar = new Button(compositeBotoes, SWT.NONE);
      limpar.setText("Limpar");
      limpar.setData("limpar");

      login = new Button(compositeBotoes, SWT.NONE);
      login.setText("Login");
      login.setData("login");
   }

   public void display() throws Exception {
      final Display display = Display.getDefault();
      Rectangle bounds = display.getBounds();
      shell.setLocation(bounds.x
            + (bounds.width - shell.getBounds().width) / 2, bounds.y
            + (bounds.height - shell.getBounds().height) / 2);

      shell.open();
      shell.forceActive();

      while (!shell.isDisposed()) {
         if (!display.readAndDispatch()) {
            display.sleep();
         }
      }

      display.dispose();
   }

   public static void main(String[] args) throws Exception {
      new LoginSWTView().display();
   }
}

Outra novidade é que, atendendo aos pedidos de diversos usuários, agora é possível utilizar a parte client do genesis simplesmente colocando os jars no classpath. O Edgar postou no seu blog, de forma bem didática, como funciona o binding e como utilizá-lo com Swing num sistema de locadora. Vale a pena conferir.

Caso tenham sugestões ou dúvidas a respeito do genesis, podem perguntar aqui no blog ou na lista de discussão do projeto, conforme explicado na doc em português do framework.

Vale a pena abstrair? – Parte 2

setembro 22nd, 2006

O post “Vale a pena abstrair?” gerou muito mais comentários do que eu esperava. Infelizmente não pude postar uma resposta antes devido a diversas razões, mas agora vamos finalmente ao round 2 da discussão.

Primeiro, vamos deixar claro o objetivo do post anterior, pois muitos de vocês aparentemente entenderam algo diferente do que eu quis dizer (ou eu escrevi algo diferente do que eu estou pensando :-P). A minha intenção era mostrar que criar diversas interfaces e factories e camadas de abstração indiscriminadamente, na ilusão de que isso tornará mais fácil fazer mudanças no futuro, simplesmente acrescenta complexidade ao código e acaba sendo inútil no final. Ponto. Foi só isso. Os DAOs foram um exemplo, e eu os citei porque antigamente (3-4 anos atrás, veja só), era costume ter uma DAOFactory, que era uma interface, uma OracleDAOFactory, que era a implementação, o UsuarioDAO, interface, e o UsuarioOracleDAO, a implementação. Contudo, foi um exemplo infeliz, porque quase todos os comentários focaram no exemplo ao invés do assunto que ele ilustrava, mas houve vários pontos interessantes que gostaria de comentar. Vamos um de cada vez:

Fabio Kung:

Eu discordo no ponto de não abstrair o framework de ORM. Acho útil abstrair não para trocar fácil de banco de dados, mas sim para otimizações que possam ser necessárias. É comum acontecerem casos que você precisa abrir mão das vantagens do ORM e acessar o banco direto via jdbc, ou persistir o objeto em um lugar diferente (num arquivo xml, por exemplo) porque o banco é legado e você não pode criar outra tabela).

Nada num DAO sem interface impede isso. Se eu declarar meu DAO como:


public class UmDAOQualquer  {
    // ...
    public List<EntidadeQualquer> findByAlgumCriterio(String umaPropriedadeQualquer) {
        // ...
    }
}

O que te impede de implementar o método com JDBC ou XML? No caso de exceções, pode-se usar um modelo genérico de exceção ou ainda as exceções específicas disponíveis nas novas versões do Hibernate. Não é necessário ter interfaces pra isso.

Rubem Azenha:

Michael, o problema é que o pessoal as vezes pode usar isso como desculpa para fazer as coisas mal feitas…

No caso o DAO por exemplo, eu prefiro usar DAOs, com interface, abstraido e tudo mais. A questão não é só “e se a gente trocar de banco” mas também da testabilidade e da manutenabilidade (existe essa palavra?) da aplicação. Se você colocar no teu objeto de negócio a session direto do Hibernate, como você vai fazer os seus testes unitários? E se der um problema? Será que é no DAO ou na classe de negócio? Com o código isolado, fica *bem* mais fácil encontrar o problema, bem mais fácil de dar manutenção, bem mais fácil de reaproveitar.

Veja o ponto acima sobre interfaces. Para testes unitários, você pode criar seu DAO como subclasse do original, usar um framework de mock objects ou algo do gênero. Contudo, essa questão de testes unitários e a distinção entre negócio e acesso a banco de dados é interessante.

Por exemplo, em projetos que usam DAO extensivamente, já vi várias vezes classes de negócio que simplesmente delegavam para os DAOs, sem adicionar lógica nenhuma (as vezes convertiam exceções, mas isso deveria ser feito com aspectos, anyway). Nesse caso, o uso de DAOs é completamente desnecessário.

Em diversas situações, quando existem DAOs e classes de negócio interagindo, normalmente você tem, efetivamente, um problema de purismo OO. Eu sou a favor de manter a lógica em Java quando faz sentido, mas esse “quando faz sentido” é o que a maioria nunca aplica. Por exemplo, aplicar lógica de negócios em Java onde será necessário carregar um grande número de entidades em memória somente para filtrá-las quando isso poderia ser feito num select simplesmente limita a escalabilidade da aplicação.

Em outros casos, os metódos do DAO são resultado de otimizações e não um design natural. Por exemplo, tinha-se um processo lento em Java; muda-se isso para stored procedures em banco e, além de perder legibilidade, a performance degrada e faltam recursos presentes na linguagem. Então chega-se a um modelo híbrido em que parte é feita pela classe de negócios e parte pelo banco, através do DAO. E aí está o ponto: neste caso, testes unitários têm muito pouco valor, pois é a interação inteira que importa. Um teste integrado seria muito mais interessante neste caso ou talvez o DAO devesse ser eliminado e os métodos movidos para a classe de negócio.

Por fim, não estou condenando a separação entre DAO e camada de negócio; apenas mencionando que os casos mais comuns, na verdade os DAOs não deveriam existir ou a separação agrega pouco valor ao design, as vezes simplesmente tornando o mesmo mais complexo. Concordo que a separação deve existir sempre que necessário, mas a necessidade de interfaces em si só costuma surgir em raros casos.

Gyowanny:

Todos os argumentos são válidos, mas e se eu não quiser usar Hibernate? Se vocês só trabalharam a vida toda com aplicações de grande porte, usando JEE e tudo o mais, com certeza um framework de mapeamento O/R se faz necessário, mas já tive casos, com aplicações JSE de médio porte, onde o Hibernate deixou a aplicação pesada e então fez-se necessário utilizar o acesso a JDBC direto, ou seja, se eu tivesse abolido as interfaces DAO da aplicação o esforço para efetuar essa mudança seria muito maior, sem contar que eu perco a liberdade de poder usar outros frameworks de persistência.

Alguns esquecem que um dos requisitos básicos para um sistema bem projetado é a existência de acomplamento fraco ou abstração entre as camadas , principalmente na camada em questão.

Bem, aqui temos diversos pontos interessantes. Primeiro, que o Hibernate deixa sistemas de médio porte pesados. Eu já fiz alguns sistemas menores com Hibernate para uso pessoal e nunca tive problemas desse tipo. Normalmente, os problemas de performance que se tem com Hibernate são causados por falta de configuração apropriada e/ou mau uso das funcionalidades. Contudo, como não conheco o projeto, vou assumir que sua afirmação está correta.

Partindo desse pressuposto, se o problema de performance foi descoberto depois de uma parte significativa do código ter sido escrita, então o uso dos DAOs não foi um benefício para o projeto: o erro foi a falta de testes de performance, quer na definição da arquitetura, quer durante o desenvolvimento. Se o problema fosse detectado no começo do projeto, provavelmente não haveria diferença de tempo na substituição do Hibernate por outra solução, até porque você tem que levar em conta o tempo requerido para projetar e implementar os DAOs na comparação.

Não estou condenando o uso de DAOs nesse projeto especificamente, mas sim mostrando que o motivo usado para justificar o seu uso não mostra nenhum benefício real e sim que existia um outro problema.

Continuando…

kalecser:

Se não abstrair o acesso aos dados, seja ele via framework OR ou não, é impossível testar unitariamente o código, é impossível entregar uma funcionalidade sem modelar a parte de acesso a dados e a sua aplicação terá, de cara, uma dependência estática ainda mais gosmenta que as ditas interfaces e abstrações, o banco de dados :P

Sim, isso concordo. Mas na realidade, dificilmente não usamos Hibernate, que é um framework ORM, então criar factories e interfaces e níveis e níveis de abstração não ajuda aqui…

Emerson:

Eu uso a abstração para ler de duas fontes de dados de maneira transparente. Ex: Aqui onde trabalho usamos oracle e arquivos VSAM do mainframe. Determinado Business Object pode ser persistido ou em VSAM ou no Oracle. Pode ser feito um create() de um VSAM ou da base Oracle. Isso tudo por motivos que não vem ao caso aqui, porém é a nossa necessidade. Para nós é util essa abstração.

….

No meu caso como é Oracle e VSAM o Hibernate não resolve meu problema heheh.

Sim, Emerson, o seu caso parece mesmo ser uma excelente exemplo de benefício do uso dos DAOs e, nesse caso, até mesmo de interfaces. Aí sim vale a pena abstrair, porque você tem um caso de uso que justifica isso.

Um outro exemplo seria num produto que deve ser estendido pela equipe de desenvolvimento de quem compra e que pode se reutilizar das classes usadas por outros projetos do cliente. Nesse caso, também seria importante poder trocar o mecanismo de persistência.

Marcos Silva Pereira:

No meu caso, não é apenas abstrair o banco de dados, mas abstrair o acesso aos dados. Definir uma interface é mesmo desnecessario se vc já usa um ORM da vida, mas ao menos no meu caso, acho valido criar um componente para eu dizer: ei, me dê os dados e não me preocupar se ele usa criteria, hql, jdbc ou o que seja. A responsabilidade é dele, quero apenas os dados.

É justamente aí que talvez DAOs tenham uma utilidade que não seja necessariamente abstrair O banco de dados mas sim o acesso aos dados. É mais sobre Separation of Concerns do que sobre ter que mudar o tipo de repositorio.

Comentário interessante, mas que faz sentido somente quando não se cai nas situações que citei acima. Clareza e separação de responsabilidades são importantes; agora ficar apenas delegando e delegando métodos sem acrescentar comportamento é simplesmente adicionar complexidade ao código.

Os outros comentários foram mais ou menos semelhantes (ou concordaram comigo, hehehe), então não vou citá-los aqui. Se aqueles que escreveram acharem que esqueci de algum ponto, podem comentar nesse post.

Em resumo, só crie uma abstração quando ela fizer sentido para você. De forma mais prática: a menos que esteja desenvolvendo um produto ou framework, abstraia somente se houver mais de uma implementação e não apenas a “possibilidade de”, “e se um dia eu precisar” etc.

Vale a pena abstrair?

agosto 30th, 2006

Um post do Paulo sobre abstração de DAOs me fez lembrar de escrever sobre este assunto.

Durante muitos anos, eu fui adepto do desacoplamento e da abstração a todo custo. Eram factories com interface, que eram implementadas por uma abstract factory, que achava a própria implementação delas através de properties (sim, isso foi antes dos containers de DI, era uma boa prática pra época) e que sempre produziam interfaces e por aí vai. Os DAOs tinham interfaces e suas factories também e tudo era lindo.

Isso foi há pouco mais de 5 anos e hoje faz uns 2 anos e meio que parei com isso. Por quê? Bem, a análise do que eu havia feito naquela época me mostrou que ter esse princípio como norma geral é uma péssima idéia. Vou tomar como exemplo o casos dos DAOs.

No começo, isso fazia algum sentido, porque a idéia dos DAOs era permitir que você trocasse de banco de dados. Se seu sistema usava só JDBC puro e não havia triggers e afins no banco, no caso da remota possibilidade de trocar de banco, havia alguma vantagem nisso. Agora, quantos de vocês já viram isso acontecer? Mesmo quando acontece, dependendo das diferenças de funcionalidades utilizadas dos dois bancos e da forma como a abstração foi implementada, uma reescrita de tudo acaba sendo necessária. Além disso, nos grande maioria dos casos em que a mudança não ocorre, o quanto isso atrasa o ciclo de desenvolvimento? E aquele monte de interfaces inúteis, que só servem para deixar seu deploy mais lento e seu code completion mais poluído? Fora o fato de fazer os juniors entenderem por que isso é necessário. Obviamente, eu não estou considerando aqui o caso de produtos “genéricos” ou ferramentas que realmente tem que funcionar com mais de um banco desde o primeiro dia e, mesmo assim, estou supondo que o Hibernate ainda não existia.

Quando o Hibernate e seus semelhantes surgiram, aí as coisas passaram a fazer muito menos sentido. O problema principal que era poder usar outros bancos foi coberto. Aí as pessoas começaram a raciocinar: e se eu quiser trocar o Hibernate? Bem, se você quiser fazer isso, provavelmente sua aplicação inteira vai acabar mudando, a menos que você vá mudar para EJB 3 (o que, por sinal, não faz sentido na maioria dos casos). Escondendo o Hibernate você perde acesso a funcionalidades avançadas e outras delas “vazam” pelo código, como o uso de Transfer Objects para evitar a carga lazy de algumas propriedades e coisas do tipo.

O fato é que nos últimos anos todos nós ouvimos que devemos fazer a coisa mais simples que funciona. E os sistemas não funcionariam sem essa parafernalha toda? Então, por que estamos construindo algo de que não sabemos se vamos precisar? Da próxima vez que achar que precisa de interfaces ou abstrair uma implementação, verifique o custo-benefíio antes de sair codificando.

Duvidas sobre o binding Swing do genesis

agosto 24th, 2006

Começaram a aparecer dúvidas sobre o post que fiz a respeito do binding Swing suportado pelo genesis. Aproveito para responder aqui as perguntas do Tetsuo, para que fique mais visível para quem visita o blog:

Há como fazer o binding com outras propriedades dos componentes, como ‘enabled’, ’selected’? Por exemplo chamar ‘form.setNome_enabled(false)’ para desabilitar um textfield. Isto seria perfeito para fazer ’subcutaneous testing’ da lógica das telas sem ter que instanciar componente visual algum, já que toda a lógica poderia ser feita diretamente no bean.

Isso é suportado pelo genesis há cerca de dois anos, de forma direta. Uma coisa coisa é o suporte condicional do genesis, que permite controlar a visibilidade e habilitação de widgets, além de permitir a limpeza dos dados e a chamada automática de métodos sob alguma condição.

Por exemplo, se você tivesse um form onde a pessoa deve inserir o nome do cônjuge (i.e., esposo/esposa), mas quer que esse campo esteja disponível somente quando o indivíduo for casado, pode-se fazer:


@Form
public class ExemploEnabledWhenForm {
   private boolean casado;
   private String nomeConjuge;

   public boolean isCasado() {
      return casado;
   }

   public void setCasado(boolean casado) {
      this.casado = casado;
   }

   @EnabledWhen("form.casado")
   public String getNomeConjuge() {
      return nomeConjuge;
   }

   public void setNomeConjuge(String nomeConjuge) {
      this.nomeConjuge = nomeConjuge;
   }
}

Esse exemplo encontra-se na documentação do genesis.

Outra coisa é trabalhar com seleções e com o populamento de widgets como tabelas, comboboxes e listas. Para isso, o genesis provê a anotação @DataProvider, que permite definir qual propriedade manterá a opção selecionada, como no exemplo abaixo, também retirado da documentação do projeto:


@Form
public class ExemploDataProviderForm {
   private Estado estado;

   public Estado getEstado() {
      return estado;
   }

   public void setEstado(Estado estado) {
      this.estado = estado;
   }

   @DataProvider(objectField="estado")
   public List populaEstados() {
      // retorna uma List contendo instâncias de Estado
   }

   // ...
}

Uma outra dúvida: quais as dependências mínimas para rodar a aplicação no cliente? Sem banco, sem thinlet, só swing+genesis. Tenho que embutir o runtime do werkz? jxpath? beanutils?

Bem, isso depende muito das funcionalidades que você usar. A melhor maneira é verificar no desktop_build.xml da versão que você baixar quais jars do path run.standard.classpath você precisa. Ê fácil deduzir quais uma vez que você tenha lido a documentação do genesis.

Aproveito para lembrar que o genesis possui uma lista de discussão em português em usuarios@genesis.dev.java.net, onde outras pessoas que usam o framework poderão responder e tirar proveito das suas perguntas (e das nossas respostas). Para assinar, basta mandar um email para usuarios-subscribe@genesis.dev.java.net e responder a mensagem que o servidor lhe enviará.

Suporte SWT no HEAD

agosto 23rd, 2006

Depois da release, foi integrado no HEAD suporte a SWT no binding. Pode-se usar o binding assim:


Shell shell = new Shell(SWT.TITLE | SWT.CLOSE);
// configure o shell
SwtBinder  binder = new SwtBinder(shell, form = new UserListForm(), this);
binder.bind();

O primeiro parâmetro deve ser um org.eclipse.swt.widgets.Composite. O exemplo useradmin já foi atualizado também para incluir a versão SWT. Para os mais curiosos, segue um link para a tela de listagem de usuários do exemplo. Agora estamos atualizando a doc para cobrir o SWT. Aguardem mais novidades.