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

img

Atenção: por essa edição ser muito antiga não há arquivo PDF para download.Os artigos dessa edição estão disponíveis somente através do formato HTML. 

Eclipse Visual

Primeiros Passos com o SWT

 

Conheça na prática o SWT, que permite criar aplicações gráficas multiplataforma, como responsividade e aparência de aplicações nativas, sem sacrificar a compatibilidade

 

Fernando Lozano

 

Ao iniciar o Projeto Eclipse há cerca de cinco anos, a IBM decidiu criar um tookit gráfico alternativo ao Swing – O SWT. Com o tempo e o sucesso do Eclipse, muitos desenvolvedores passaram a considerar seriamente o SWT como alternativa ao tookit gráfico padrão do Java, o Swing Hoje, além de ser adotado no Eclipse e seus muitos plug-ins, o SWT é utilizado por várias aplicações populares, como o RSSOwl, um agregador de notícias RSS (Figura1) e Azureus, um cliente para a rede de compartilhamento de arquivos BitTorrent (e atualmente um dos projetos mais ativos no SourceForge).

Apesar das críticas de que o SWT fragmentaria a plataforma Java, e das discursões inflamadas sobre a qual seria o melhor toolkit gráfico, o SWT é visto por cada vez mais profissionais e empresas como uma alternativa viável (ou superior) para o desenvolvimento de aplicações gráficas com Java.

Este artigo apresenta os primeiros passos no desenvolvimento SWT, para usuários do Eclipse e também para usuários de outros IDEs (Nada obriga  o desenvolvedor de aplicações SWT a utilizar o Eclipse).

 

Todos os exemplos neste artigo foram testados com JVMs livres, entre elas Kaffe, JamVM, SableVM e GCJ – além das JVMs 5.0 e 1.4.2 as Sun.

 

img

 

Figura 1. Aplicação SWT rodando sobre o Kaffe VM em Linux

 

Arquitetura do SWT

O SWT foi criado para ser ao mesmo tempo poderoso, leve e multiplataforma. Para isso utiliza o máximo possível dos recursos nativos da plataforma, mas sem perder portabilidade. Há versões do SWT diferentes para cada plataforma suportada – estas variam desde o PocketPC com J2MW, até sistemas Linux e Solaris de 64bits, passando por QNX, MAC OS  Windows e outras variantes do Unix. Mas a API exposta pelo SWT para aplicações é independente de plataforma, com cad um implementando esta API usando código Java específico.

Nesse sentido, pode-se considerar que o SWT é uma extensão da JVM. Para entender o motivo, podemos fazer uma analogia com a classe java.io.File. Uma aplicação Java utiliza os mesmos métodos de para verificar a existência de um arquivo (exists()) e para obter seu tamanho (length()), mas a implementação destes métodos varia radicalmente para cada plataforma, pois é necessário utilizar os recursos específicos do sistema operacional para essas operações.

O fato da classe File ser implementada de forma diferente em cada plataforma não impede, por exemplo, que uma aplicação Java desenvolvida e compilada em Windows rode sem modificações no Mac OS. Da mesma forma, o fato de se desenvolver uma aplicação SWT utilizando a versão para Linux, não impede que a aplicação seja executada, sem modificações ou recompilação, em Windows ou outras plataformas. Basta que esteja disponível a versão específica do SWT. O uso de código nativo pelo SWT é um detalhe interno da sua implementação, que não afeta as aplicações escritas para este toolkit.

 

Preparando o ambiente

Na Listagem 1 está uma aplicação SWT simples. Antes de explicar o código, vamos usar essa aplicação para validar a configuração do ambiente de desenvolvimento, e para verificar a instalação do SWT (caso não seja utilizado o Eclipse). Para acompanhar os passos de configuração a seguir, crie um projeto no Eclipse com a nova classe. A Figura 2 mostra a aplicação executando em Linux (Fedora) com Gnome e Windows XP.

Em princípio é possível desenvolver aplicações SWT utilizando apenas o download básico do Eclipse Platform + JDT, ou mesmo sem utilizar o Eclipse em absoluto (veja o quadro "SWT Fora do Eclipse"). Mas o PDE e o plug-in Visual Editor (VE) fornecem capacidades adicionais que poderão interessar ao desenvolvedor. O suporte oferecido pelo PDE e VE, entretanto, ainda é voltado principalmente para o desenvolvimento de plug-ins e não de aplicações SWT independentes. Isso leva alguns a preferir não usar esse suporte. Para os curiosos, Figura 3 mostra a edição de uma tela simples no VE.

 

Embora seja possível usar o VE sem o PDE, esta configuração fornece apenas suporte ao desenvolvimento Swing e não a SWT.

 

Devido a mudanças na forma como o Eclipse 3.1 empacota seus plug-ins em relação a versões anteriores, o leitor pode preferir obter o SWT isoladamente, ou então baixar o PDE. (Lembrando que antes da versão 3.1 o PDE não fornecia nenhuma facilidade específica para o desenvolvimento SWT, exceto pela documentação.)

A Tabela 1 apresenta várias configurações possíveis do Eclipse, o tamanho total

de download e recursos oferecidos por cada uma para o desenvolvimento SWT.

 

Listagem 1. Primeira aplicação SWT:OiSwt.Java___________________

 

import org.eclipse.swt.SWT;

import org.eclipse.SWT.layaout.RowLayout;

import org.eclipse.SWT.widgets.Display;

import org.eclipse.SWT.widgets.Label;

import org.eclipse.SWT.widgets.shell;

 

public class OiSwt {

     public static void main(String[]args){

          Display display = new Display();

          Shell.shell =new Shell (display, SWT.DIALOG_TRIM);

          shell.setText(“Oi do SWT”);

          shell.setLayout (new RowLayout());

           Label msg = newLabel(shell, SWT.NULL);

          msg.setText(“\nNem parece que fui escrito em Java :-)\n”);

          shell.pack();

          shell.open();

           while (!shell, isDisposed()) {

              if(!display.readAndDispatch()){

                display.sleep();

             }

           }

           display.dispose();

     }

}

 

img

img

 

Figura 2. Aplicação mínima em Linux e Windows

 

img 

Figura 3. Editor visual VE para aplicações SWT

 

 

Componentes

Tamanho total do download (versão 3.1.1)

Facilidades para desenvolvimento SWT

Plataforma + JDT

37Mb

. Nenhum, fora os fornecidos pelo JDT para aplicações não-SWT

Plataforma + JDT+PDE

42 Mb

. Executar aplicação SWT

. Definição da variável de classpath para referenciar bibliotecas inclusas no próprio Eclipse

. Javadocs do SWT (dentro da documentação da Eclipse API)

Eclipse SDK

45Mb

. As mesmas facilidades da Plataforma + JDT + PDE, mas inclui os fontes do Workbech, do SWT e de plug-ins

Plataforma + JDT + PDE + GEF + EMF + VE

53 Mb

. Assistentes para criação de aplicações SWT e edição visual destas aplicações

 

Configuração do Eclipse 2.x13.0.x

Em versões até a 3.0, a SWT pode ser encontrado dentro do plug-in org.eclipse. swt.<plataforma> _ <versão>, por exemplo org.eclipse.swt.win32_3.0.2 no Windows, ou org.eclipse.swt.gtk_3.0.2 no Linux. Dentro deste plug-in, a pasta ws/<plataforma>, por exemplo ws/win32 (ou ws/gtk), fornece um ou mais pacotes jar contendo as classes do SWT. Todos devem ser inseridos como jars externos no classpath do projeto, como ilustra a Figura 4.

Se você tem o PDE instalado, pode usar a variável ECLIPSE_HOME e assim fazer uma referência relativa aos jars do SWT. Se vários desenvolvedores trabalham no mesmo projeto, o uso de uma variável permite que cada um tenha o Eclipse instalado numa pasta diferente, e que mesmo assim os metadados do projeto (arquivos .project e .classpath) sejam compartilhados via CVS. Para usar essa variável, abra as propriedades do projeto e dentro da aba Libraries da categoria, clique em. Então selecione Add Variable a variável e clique no botão Expand para selecionar os pacotes do SWT dentro da sua instalação do Eclipse (veja a Figura 5).

Se neste ponto o leitor tentar executar a aplicação, verá um erro como:

 

Exception in thread “main” java.lang. UnsatisfieldLinkEror:

    no swt-pi-gtk-3064 in java .library.path

 

Isso acontece porque ainda é necessário indicar para a JVM onde localizar as bibliotecas nativas do SWT. Precisamos alterar as configurações de execução: use o comando Run |Run para abrir a configuração criada pelo Eclipse para nosso exemplo OiSwt e selecione a aba Arguments. Depois, na caixa VM Arguments forneça o caminho para as bibliotecas nativas do SWT. Este caminho está no mesmo plug-in onde buscamos os pacotes jar, só que na pasta os/<so>/<arquitetura>, por exemplo os/win32/x86 ou os/linux/x86 (veja um exemplo na Figura 6). Modificada a configuração de execução, nossa aplicação SWT deverá funcionar corretamente também dentro do Eclipse.

 

Mesmo sem ter o PDE instalado, os argumentos de um programa podem ser constrídos a partir de variáveis pré-definidas pelo Eclipse, para montar o caminho para os jars do SWT. Experimente usar {system:OS}_3.0.2/os/{system:OS}//{sytem:ARCH} em vez de eclipse/plugins/org.eclipse.swt.gtk_3.0.2/os/linux/x86, ou qualquer que seja o caminho em sua plataforma.

 img

Figura 4. Configuração do classpaph de um projeto SWT no Eclipse 3.0.x

 

img

Figura 5. Utilizando a variável definida pelo PDE pra simplificar a localização das classes SWT dentro do Eclipse

 

img

Figura 6. Configuração de execução para uma aplicação SWT no Eclipse 3.0.2

 

Configuração do Eclipse 3.1.x

A partir do Eclipse 3.1 foi adotada uma nova forma de se empacotar plug-ins para instalação dentro do Workbench. Cada plug-in é um único arquivo jar, em vez de uma pasta contendo vários arquivos e subpastas. Na maioria dos casos, isso não atrapalha o uso de bibliotecas Java embutidas nos plug-ins, como o JUnit, mas impede que a JYM acesse as bibliotecas nativas dentro da implementação do SWT específica para a plataforma.

Esse problema não afeta o Eclipse em si porque ele usa um classloader customizado, capaz de lidar com esta questão e com dependências entre plug-ins. Este classloader está incluso no Rep, mas é um tanto complicado incorporá-lo a aplicações SWT "puras". Será mais fácil descompactar o jar do plug-in em outro diretório, e depois configurar o projeto e a aplicação de forma semelhante ao feito para a versão 3.0 - só que buscando as classes e bibliotecas fora do diretório de instalação do Eclipse.

Se o PDE for instalado, será adicionado um tipo de configuração de execução especializado para aplicações SWT, que roda aplicações sob o classloader do Eclipse em vez de sob o classloader padrão da JYM. Assim é possível carregar as bibliotecas nativas que estão dentro do pacote jar do SWT, e o processo fica bem mais simples.

Primeiro, configure o classpath do projeto para incluir o SWT específico à sua plataforma. Este é apenas um arquivo jar, conforme vemos na Figura 7. (Observe o uso da variável de classpath para referenciar o SWT sem embutir o diretório de instalação do Eclipse na configuração do projeto.) Depois, no momento de executar a aplicação, escolha Run | Run As> SWT Application (Figura 8). A aplicação irá funcionar diretamente, sem necessidade de customizar a configuração de execução.

 

img

Figura 7. Configuração do projeto SWT para o Eclipse 3.1.x, com PDE

 

img

Figura 8. Execução de aplicação SWT dentro do Eclipse 3.1.x, com PDE

 

Explicando o programa SWT mínimo

Agora que vimos como configurar o Eclipse para o desenvolvimento com SWT, passamos a descrever o código do exemplo mínimo OiSWT.

 

Classes fundamentais

Duas classes são essenciais em qualquer aplicação SWT: Display e Shell. A classe Display faz a comunicação com o subsistema gráfico nativo da plataforma. Um Shell é uma janela padrão, com barras de título, botão de minimizar etc. O exemplo cria um objeto Display, que é o pai de um objeto Shell. Este Shell, por sua vez, é pai de um Label, dentro do qual são inseridos alguns caracteres de final de linha ("\n") para que o texto não fique colado acima e abaixo da janela.

Depois que todos os filhos do Shell são inicializados, é chamado o método pack(), que posiciona os componentes filhos de acordo com as regras de

layout estabelecidas para eles. A janela é então tornada visível pela chamada a open(), e é iniciado o loop de eventos, obrigatório em qualquer aplicação SWT.

 

Loop de eventos

O loop de eventos (event loop) recebe eventos gerados pelo ambiente gráfico da plataforma e os traduz para os eventos do SWT, chamando readAndDispatch(). Esse loop continua executando até que o Shell seja fechado pelo usuário (a verificação é feita com isDisposed()). Dentro do loop de eventos, a aplicação "dorme" por alguns segundos com sleep(), sempre que não houver eventos nativos aguardando por tradução e tratamento. Desse modo, a aplicação não fica consumindo tempo de processador sem estar fazendo nada de útil.

 

Liberando recursos

 

Depois que o loop de eventos é finalizado, a aplicação deve liberar quaisquer recursos que ainda estejam em uso (como janelas e fontes). Por isso a chamada a display.dispose(). Não precisamos chamar dispose() para o Shell porque ele é liberado ao ser fechado pelo usuário. Além disso, a liberação de um Shell libera automaticamente todos os seus componentes filhos.

 

Indo além

O que vimos é o esqueleto básico de uma aplicação SWT. Uma aplicação mais sofisticada iria diferir apenas por construir mais componentes gráficos e capturar eventos desses componentes. Nesse exemplo simples não foi necessário capturar eventos, porque o Shell irá responder automaticamente ao evento de fechamento, finalizando o loop de eventos e encerrando a aplicação.

Para comparação, a Listagem 2 mostra uma aplicação equivalente escrita em Swing. Embora neste caso a versão Swing seja bem menor, aplicações reais não terão diferença significativa de quantidade de linhas. O quadro "Comparando SWT e Swing" aponta semelhanças e diferenças entre os dois toolkits.

Daqui em diante, explicamos os conceitos fundamentais para a construção de aplicações SWT.

 

Listagem 2. Primeira aplicação Swing: OISwing.java                                          

 

import javax.swing.JFrame;

import javax.swing.JLabel;

 

public class OiSwing {

  public static void main(Strings[] args){

      JFrame frame = new JFrame();

       frame.setTitle (“Oi do Swing”);

       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

 

       JLabel msg=new JLabel (“\nOi do Swing\n”);

       frame.add(msg);

        frame .pack();

       frame.setVisible(true);

   }

}

 

Pacotes, Widgets e Containers

As classes utilizadas e citadas neste artigo estão em cinco pacotes principais do SWT:

org.eclipse.swt- Inclui constantes comuns usadas em todos os demais pacotes, e exceções gerais.

org.eclipse.swt.events - Classes para tratamento de eventos.

org.eclipse.swt.graphics - Classes representando fontes, cores e outros recursos que não sejam componentes visuais.

org.eclipse.swt.layout - Classes de layout e de dados de layout.

org.eclipse.swt.widgets – Componentes visuais, diálogos e janelas.

 

No SWT, os componentes visuais (como botões, caixas de texto, checkboxes etc.) são chamados de widgets, sendo todos derivados da classe Widget. A maioria dos componentes visuais utilizados diretamente em aplicações são subclasses de Control. Componentes que podem conter barras de rolagem são por sua vez subclasses de Scrollable. A Figura 9 apresenta o relacionamento entre estas três classes e outras classes visuais muito usadas em aplicações SWT.

 

É possível inserir um componente Swing (ou AWT) dento de um container SWT. Mas esta prática não é recomendada, pois o componente Swing ficará em um “universo paralelo”, não sendo integrado ao loop de eventos nem ao gerenciamento de layout dos componentes SWT. A razão de permitir o uso de componentes Swing em aplicações SWT foi apenas possibilitar a criação de um editor visual de telas Swing no Eclipse (uma parte do VE), e facilitar a integração com ferramentas pré-existentes ao Eclipse

 

Alguns widgets têm a capacidade de ser pais de (conter) outros widgets, sendo chamados de containers. Todos os containers são subclasses de Composite.

Além dos containers específicos, pode-se usar um Composite diretamente como um container genérico - por exemplo para colocar uma moldura em volta de um grupo de componentes, ou para simplificar a definição de regras de layout (ex.: para fazer um conjunto de componentes mover-se em bloco).

Os componentes mais sofisticados, como abas (TabFolder), barras de ferramentas (Toolbar) e árvores (Tree), são na maioria também subclasses

de Composite. Isso Também é verdade Widget para Canvas, uma área de desenho livre da qual deriva o Shell; e o StyledText, que é a base do editor de código do Eclipse.

 

Um widget deve receber uma referência ao seu pai no momento em que é criado. Pode também receber estilos, definindo as partes do seu comportamento e aparência que não devem mudar durante a execução da aplicação

...

Quer ler esse conteúdo completo? Tenha acesso completo