Introdução ao Lightweight User Interface Toolkit (LWUIT)



por Biswajit Sarkar
14/08/2008

Java ME nos permite escrever aplicações, de um modo geral, para uma vasta gama de portáteis de pequenos dispositivos que suportam a plataforma. Embora as funcionalidades básicas usuais funcionem bem em todos os dispositivos suportados, a área que levantam problemas para os desenvolvedores é a interface do usuário. Implementação nativa de javax.microedition.lcdui - a principal API para UIs em Java ME - difere tão amplamente de um dispositivo para outro, que a manutenção independente de um dispositivo, uniforme do aspecto visual e comportamento são virtualmente impossíveis.

Não apresentar aspecto visual e comportamento uniforme, não é a única razão por que os desenvolvedores esperam por algo melhor que possa vir. O pacote javax.microedition.lcdui não suporta componentes e capacidades que podem satisfazer plenamente as expectativas do usuário nos dias de hoje. É neste contexto que a chegada do Lightweight User Interface Toolkit (LWUIT) é tão interessante. LWUIT oferece uma vasta gama de elementos para a construção de UIs. Embora alguns desses elementos também estão disponíveis embaixo do lcdui, existe um número de novos elementos que permitem que desenvolvedores de aplicação desenhem UIs, que se aproximam do seu desktop, contrapartidas em termos de sofisticação visual. Mesmo os componentes que também são oferecidos por lcdui, foram reforçados. E LWUIT não está apenas sobre os novos componentes. A API suporta uma vasta gama de novas funcionalidades, também - theming, transitions e mais.

Os desenhistas do LWUIT  afirmam que esta API foi inspirada e modelada em Swing. Isto tem uma série de implicações. Uma implicação importante é que os widgets (elementos) são prestados pelo código LWUIT e não são derivados de equivalentes nativos. Isto, assegura a independência de dispositivo e uniformidade visual.

A arquitetura de adaptação do Swing  também significa que o código para desenhar um componente está bem definido, e é distinto do código que define o seu comportamento. Por isso, é possível substituir o código  renderizado para executar uma
Neste artigo, veremos alguns dos importantes recursos e funcionalidades que temos mencionado acima. Nossa visão de LWUIT discutirá os seguintes aspectos:

  • Widgets.
  • "Infra-estrutura" itens como Recursos (Resource), Gerenciador de Interface de Usuário (UIManager) e assim por diante.
  • Funcionalidades como themes e transitions.


LWUIT Widgets


Figura 1. A hierarquia de classe widget


Uma versão simplificada da estrutura hierárquica das classes widget no LWUIT é mostrada na figura acima, que está adaptada a partir do "Guia do desenvolvedor", previsto no pacote  LWUIT. Como vimos aqui, a classe base dos widgets é Component. Vemos também que, enquanto LWUIT suporta conhecido widgets lcdui, tais como, List e Label, que também tem um número de novos widgets, como ComboBox, Dialog, TabbedPane, e assim por diante.


Container e Form

Entre os widgets, o Container é "holder" básico, que pode conter outros componentes, incluindo outros containers. Este aninhamento de habilidade dos containers permite UIs complexas e elaboradas para serem acumuladas. A disposição dos componentes dentro de um container é o cuidado para utilizar um layout manager.
Form é um container com uma Barra de Título na parte superior em que o título do formulário pode ser escrito e uma Barra de Menu na parte inferior, para os comandos e menu. O espaço entre as duas barras é para o conteúdo painel , que carrega os componentes a serem colocados no formulário.

TabbedPane

Um TabbedPane permite um número de grupos de componentes dividirem o mesmo espaço. Cada grupo de componentes tem uma tab associada, que o usuário vê apenas o grupo correspondente a tab que tiver sido selecionada.

O arranjo de tabs padrão é no topo do painel. No entanto, é possível posicioná-las à esquerda, à direita ou no fundo do painel. A Figura 2 mostra uma tabbed pane com as tabs no topo e já na primeira tab selecionada.



Figura 2. Uma tabbed pane

Dialog
Um Dialog é um componente "always-on-top". Por padrão, um dialog é modal - ou seja, ela bloqueia a chamada thread até que sejam eliminados. Dialogs podem ser de cinco tipos:

  • Alarm
  • Confirmation
  • Error
  • Info
  • Warning


Dialogs podem ser utilizados para transmitir informações para o usuário em tempo de execução e para guardar feedback dos usuários. O tipo do diálogo seria normalmente determinar o som a tocar quando a caixa de diálogo é exibida. É possível adicionar ícones à um dialog para indicar graficamente o tipo de diálogo. A Figura 3 mostra um dialog simples de aviso com os comandos OK e Cancel.


Figura 3. Dialog de aviso OK/Cancel
Label e Button Uma Label é para exibição de imagens e textos que não podem ser selecionados e não interagem com o usuário. Um número de possibilidades alinhamento são suportados para o posicionamento da label e para o posicionamento do texto no que diz respeito à imagem na label.
A classe Button extends Label. Um botão tem states e que gera uma action event quando selecionado e clicado. Como uma Label (que é a superclasse de botões), um Button pode ter texto descritivo, uma imagem, ou ambos. Os três estados de um botão são:

  • Rollover: Este é normalmente equivalente ao botão a ser selecionado ou a receber o foco.
  • Pressed: Quando o botão foi clicado ou pressionado.
  • Default: Quando o botão é clicado ou não selecionados.

Um Button tem duas subclasses: RadioButton e CheckBox. Um RadioButton tem todas as funcionalidades de um botão. Além disso, um botão radio pode ser adicionado a um ButtonGroup, que lhe permite manter o seu estado de seleção exclusivamente dentro do grupo. Dentro de um botão grupo, apenas um botão radio pode ser pressionado por vez. Se outro botão radio é clicado, o que foi pressionado anterioriormente será desmarcado. Observe também que, uma vez que um botão radio for pressionado, clicando nele não altera o estado.

Um CheckBox é semelhante a um botão radio no sentido de que ele pode se lembrar o seu estado, se tiver sido escolhido por clique. No entanto, clicando repetitivo num check box irá mudar o seu estado e entre os selecionados e desmarcados. Outra diferença é que um check box não pode ser parte de um botão grupo.

Um número de botões, botões radio e check box são mostrados na Figura 4 abaixo. A imagem mostra que os dois primeiros botões estão no estado default, enquanto o terceiro está no estado rollover. Ambos os check box são mostrados selecionados, mas apenas um botão radio em cada grupo é selecionado.



Figura 4. Buttons, RadioButtons e CheckBoxes

Text Area
TextArea é um componente que exibe texto que pode ser editável. A edição é realizada utilizando o editor de sistema nativo, que muitas vezes abre uma nova tela. Uma área texto usa o conceito de constraints,TextField assim como o de lcdui faz. A Figura 5 mostra um formulário com uma  área texto.



Figura 5. Área texto em um formulário

List


Um List é um componente muito utilizado, que apresenta um número de itens de informações para o usuário. Os itens são apresentados em uma única coluna, mas cada item pode conter várias linhas de texto e imagens. A arquitetura model-view-controller adaptada por LWUIT torna possível fazer uma lista look apenas o caminho que pretendemos. A estrutura dos dados de uma lista é representada pela interface ListModel. Assim, uma lista não está vinculado a quaisquer estrutura de dados específicos e pode exibir informações de qualquer objeto que implementa esta interface. Do mesmo modo, a prestação de uma lista é feita por uma classe que implementa a ListCellRenderer, tornando assim possível criar o tipo de analise que o desenvolvedor da aplicação quer. A biblioteca inclui implementações padrão de interfaces que tornam mais fácil para instanciar uma lista.


Figura 6. Uma lista simples com apenas texto

A Figura 6 mostra uma simples lista com quatro itens. Compare isto com a lista mostrada na Figura 7 e a sua aparência diferente. A aplicação por trás da tela da Figura 7 implementa seu próprio renderizador para alcançar uma aparência atraente e muito filtrada.


Figura 7. Uma lista com texto multi linhas e imagens

Combo Box

O ComboBox é um componente space-saving que estabelece baixas de uma lista quando seu botão é clicado. O usuário pode então selecionar um dos itens na lista. Como ComboBox extends List, você pode usar modelos e personalizações para combo boxes, também. Figura 8 mostra um combo box com quatro itens de lista drop-down.



Figura 8. Um combo box


Suporte a Elementos Subjacentes 

LWUIT
inclui um número de elementos de suporte  "behind the scenes" que tornam possível para as características funcionais operarem. Vejamos nestes elementos, como eles trabalham.

Recursos (Resources)

Aplicações exigem frequentemente itens sem código, por exemplo, uma imagem usada como um ícone para uma Label por aplicação. LWUIT permite tais itens  ser empacotados em bundles. Um recurso bundles é essencialmente um arquivo binário que pode ser carregado em um dispositivo. Uma aplicação pode ter mais de um arquivo de recurso e cada um desses arquivos pode conter elementos de recursos Do mesmo tipo ou diferente. A seguir, são mostrados os tipos de elementos de recursos suportados:

  • Recursos de Imagem

  • Recursos de Animação
  • Fontes Bitmap
  • Localização bundles
  • Themes

Elementos de recursos individuais podem ser extraídos por um conjunto apropriado de métodos de classe de Recursos. O pacote LWUIT tem um utilitário  - o Editor Resource - para a construção de um arquivo de recursos. Arquivos de recursos também podem ser criados por um conjunto de tarefas Ant. Gerenciadores de Layout (Layout Managers) LWUIT traz o poder do gerenciador de layout sofisticado para a desenho do UIS para pequenos dispositivos. Os gerenciadores suportados são:

  • BorderLayout
  • BoxLayout
  • FlowLayout
  • GridLayout
  • GroupLayout

Esses gerenciadores de layout  trabalham no mesmo contexto do AWT e Swing. A Figura 9 mostra um exemplo de GridLayout.



Figura 9. GridLayout

Estilo (Style)
LWUIT fornece uma maneira conveniente de definir a aparência de um componente em um único ponto. Cada componente tem um objeto Style a ela associado, e os atributos relacionados com a aparência do componente pode ser definido dentro deste objeto. Os atributos são:

  • Colors
  • Fonts
  • Images
  • Margin
  • Padding
  • Transparency


Quando um componente é gerado, ele constrói um padrão de objeto Style. Os valores dos atributos desses objetos podem ser alterados em tempo de execução para modificar a aparência de um componente. Definir um  theme atualiza o conteúdo de todos os objetos Style simultaneamente, para que todos os widgets assumam a mesma aparência, tal como definido pelo tema.


Painter

O interface Painter permite que você desenhe sobre o pano de fundo de um componente. Um pintor pode ser usado para desenhar um padrão específico sobre o pano de fundo de um ou de um grupo de componentes. LWUIT O pacote prevê duas classes que implementam esta interface:


  • BackgroundPainter: Desenha o fundo de um componente baseado em seu estilo.
  • PainterChain: Cria um "chain" de painters que pode produzir um efeito camada, com cada painter desenhando um elemento.

Gerenciador de Interface de Usuário (UIManager)

Uma característica interessante do LWUIT é que gerencia a aparência de um conjunto de aplicações a partir de um único ponto.O gerenciador de Interface de Usuário (UIManager) é a classe que coordena o aspecto visual de uma aplicação. Este é um único caminho para garantir que existe apenas um objeto UIManager por aplicação. Os métodos desta classe habilita-o para impor a mesma aparência em todos os componentes e para localizar a IU.

LookAndFeel

LookAndFeel é a interface que cuida de todas as renderizações para uma aplicação. Assim, é possível personalizar completamente a aparência de uma aplicação por razões de métodos adequados a esta interface. A implementação concreta dos LookAndFeel, que vem com o pacote LWUIT, é DefaultLookAndFeel, e esta classe controla a real renderização da aparência padrão. É possível concectar em uma implementação personalizada do LookAndFeel usando o método de UIManager, setLookAndFeel .

Funcionalidades

Um aspecto muito interessante do LWUIT é que ele ultrapassa componentes e oferece recursos que nos permitem produzir muito UIS sofisticadas. Nesta seção analisamos essas características.

Animações e Transições 
A biblioteca LWUIT suporta a implementação de diferentes modos de transição de um Form para os próximos a serem exibidos. A implementação básica de tais transições é alcançada através dos mecanismos fornecidos pela interface Animation e as classes Motion, Transition, CommonTransitions, e Transition3D, que estão contidos no pacote com.sun.lwuit.animations.

A interface Animation define objetos que são animatable. Todos componentes são inerentemente animatable, como todos eles implementam Animation. No entanto, um componente deve registar-se em seu formulário pai para conseguir animação chamadas, que desempenham as tarefas animadas, para parar essas chamadas, o componente deve-se cancelar explicitamente.

Transition é uma classe abstracta que representa animação de um formulário em outro. Suas duas subclasses concretas são:

  • CommonTransitions: Existem métodos para implementar os dois tipos comuns de transições, que são Slide and Fade.
  • Transition3D: Executa transições (Cube, Fly in e Rotation) que requerem suporte dispositivo para gráficos 3D e, portanto, não funcionam corretamente em todos os dispositivos.

Movimento é uma classe que implementa equações motion. Os tipos de motion que são built-in são linear, spline e friction. É possível implementar outras variedades de motion por subclasses Motion.

Themes

Um theme define uma vista uniforme para todos os componentes visuais de uma aplicação. Por exemplo, se quiser que todos os botões na sua aplicação tenha um fundo verde, você pode fazê-lo através da definição apropriada em par key-value no seu theme. Um arquivo theme é uma lista de pares key-value, que definem os atributos relevantes. O seguinte é uma parte de um arquivo theme, que vem com a demonstração bundle LWUIT:


Menu.bgColor= 555555
Menu.bgSelectionColor= 555555
Menu.fgColor= ffffff
Menu.fgSelectionColor= 99cc00
Scroll.bgColor= 111111
Scroll.bgSelectionColor= 242627
Scroll.fgColor= AAAA00
Scroll.fgSelectionColor= ffffff
SoftButton.bgColor= 000000
SoftButton.fgColor= ffffff
TextField.bgColor= 242627
TextField.bgSelectionColor= 242627
TextField.fgColor= 99cc00
TextField.fgSelectionColor= ffffff

Um theme pode ser empacotado em um arquivo resource. Para aplicar um theme, deve-se carregar utilizando a classe Resource. O recebido hashtable deve então ser submetido para o gerenciador do UI (UIManager) para a ação necessária.

Como já visto, cada componente tem um estilo associado a ele. Quando um theme é definido, o valor de um atributo é ler o dado theme e os objetos de estilo para todos os componentes do tipo correspondente são atualizados de acordo. No entanto, existe uma exceção a esta regra: a alteração afeta apenas os atributos que não tenham sido alterados manualmente. Esta funcionalidade permite-lhe aplicar themes seletivamente.



Figura 10. Um theme

Figura 10 mostra um exemplo de um theme. O peixe na virada do botão da mão direita é animado. Outras Funcionalidades Na adição para themes e animações, LWUIT também suporta:

  • Logging: Esta é uma depuração aid que permite voce registrar informações em tempo de execução. A classe com.sun.lwuit.util.Log fornece métodos para registro informações em um arquivo de log (criado no diretório root) e também para exibir informações registradas sobre um Form e no console. Você pode utilizar as informações guardadas no arquivo de log através da API FileConnection.
  • 3D graphics: Suporta aceleração de hardware opcional em alguns dispositivos móveis para fornecer melhor desempenho.

Conclusão
No the Sun Java (TM) Wireless Toolkit, o desempenho do LWUIT é muito lento. Isto é devido a determinadas questões de arquitetura, como pelo "Guia do Desenvolvedor"  LWUIT, os problemas de desempenho não aparecem na versão 3.2 do Sprint Wireless Toolkit e superior (que tem uma arquitetura diferente). Mesmo que não tenha experimentado a Sprint Toolkit, mas carreguei a aplicação de demonstração dentro de um dos meus handsets e trabalhou muito bem. Este é o primeiro lançamento da LWUIT e com o aumento da utilização, que evoluirá dentro de biblioteca UI para ser contada - a promessa já é evidente. Também vai prosperar cada vez mais dispositivos poderosos do futuro. Desenvolvedores UI em Java ME podem agora enxergar a frente, um produto altamente satisfatório para trabalhar por um longo tempo.
Agradecimentos
Figuras 2, 3, 4, 7, 9 e 10 são  screenshots de aplicações de demonstração que fazem parte da baixa do pacote LWUIT. Recursos

Biswajit Sarkar é um engenheiro elétrico com especialização em programação em automação industrial.