sábado, 24 de maio de 2008

Ola pessoal,

Continuando no assunto da biblioteca LWUIT, resolvi fazer um menu e assim comparar também com o menu em canvas que fiz a um tempo aqui e que é o post mais acessado... disparado!!! :)
O menu também será bem simples, como foi o seu antecessor. Seu comportamento será da seguinte forma: na navegação há mudança na imagem indicando que o item está selecionado e quando clicado é disparado alguma ação, no nosso exemplo um Alert ("convencional"). Abaixo, imagens de como ficou:


As imagens do menu
Para deixar o menu com uma visualização melhor, para cada opção eu escolhi um icone e criei uma outra imagem com uma iluminação para dar impressão de que está apagado. Então, a cada vez que um icone é selecionado a imagem que foi indicada na criação do botão é trocada pela imagem que parece "acesa".
O único cuidado com essa prática é a questão de desempenho, pois se você escolher muitos ícones e icones muito grandes o desempenho pode cair muito e ao invés de ajudar, apenas piorar.

O exemplo
Para ilustrar, o exemplo consiste em apenas um MIDlet que contém um método chamado montaMenuForm( ) e que é chamado no startApp para retornar o Form que será exibido para o usuário. As imagens são carregadas no construtor.

montaMenuForm( )
É o método responsável por montar o Form com o menu e retornar para que ele seja exibido. Esse método recebe três parametros:

  • Image[] icones: Array com todos os icones que serão utilizados quando o itens estão selecionados.
  • Image[] iconesOff: Array com todos os icones que serão utilizados na criação do botão e quando o mesmo não está selecionado.
  • String[] label: Array de String para o label do botão.
Dentro do método, no inicio há a criação do Form, definição do background e configuração do layout a ser utilizado. No exemplo foi definido que será exibido 4 icones por linha e a quantidade de linhas do menu foi calculado de acordo com o número de itens do array, o trecho do código é o seguinte:
//Criando form
//Criação do Form
Form menu = new Form("Menu LWUIT");
try {
//definindo background
menu.setBgImage(Image.createImage("/background.jpg"));
} catch (IOException e) {}

//Montagem do layout
//4 colunas
int cols = 4;
//Calculando quantidade de linhas
int rows = (int)Math.floor(icones.length/4);
//Layout de exibição em grids
menu.setLayout(new GridLayout(rows,cols));
Depois de montado o layout, é hora de adicionar os botões e definir o comportamento de cada botão. Para isso será feito um loop pelo array de imagens e em cada interação serão executadas as seguintes ações:
  • Criação de um novo botão, com o texto e a imagem do array de imagens "não-selecionadas" (utilizando o indice do loop). A forma de instanciar o novo botão é new Button(label[i], iconesOff[i]).
  • Definir a imagem que será exibida quando o item do menu estiver selecionado, através do método setRolloverIcon passando como parametro a imagem do array de imagens selecionadas, também de acordo com o indice do loop.
  • Definir a imagem que é exibida quando o item é clicado, através do método setPressedIcon passando como parametro a imagem do array de imagens selecionadas, também de acordo com o indice do loop.
  • Quando um botão é selecionado, o LWUIT coloca automaticamente uma cor indicando a seleção do botão. Para isso não acontecer e "atrapalhar" o comportamento usamos o método setBgTransparency(0).
  • O normal de um botão é ter sua borda desenhada para melhorar a visualização do componente. Porém, como estamos utilizando em um menu e o foco é a imagem a ser mostrada, a borda pode não ser desenhada. Para providenciar isso, iremos utilizar o método setBorderPainted(false).
  • E por fim, o comportamento do botão precisa ser controlado por alguém e nesse caso, o midlet do exemplo é quem implementa a interface ActionListener e que deverá ser passado como parametro para o método addActionListener.
O código do loop e criação do botão segue abaixo:
//Criando botões e adicionando ao grid
for ( int i = 0; i < icones.length; i++ ) {
b = new Button(label[i], iconesOff[i]);
//imagem para exibir ao selecionar botão
b.setRolloverIcon(icones[i]);
//imagem para exibir ao clicar no botão
b.setPressedIcon(icones[i]);
//Removendo o fundo de seleção do botão
b.getStyle().setBgTransparency(0);
//alinhamento e posição do texto do botão
b.setAlignment(Button.CENTER);
b.setTextPosition(Button.BOTTOM);
//não desenhar borda no botão
b.setBorderPainted(false);
//indicando o listener do botão
b.addActionListener(this);
//adicionando o botão ao form
menu.addComponent(b);
}
Tratando o uso do botão
Quando o usuário clica no botão é necessário tratar esse botão. Esse tratamento é feito através do método actionPerformed na classe que implementar a interface ActionListener. No nosso exemplo isso é feito no midlet da aplicação.
A programação desse método pode ser feita conforme cada programador desejar, o importante nesse ponto é identificar qual botão foi clicado e ai direcionar corretamente o usuário. O método recebe o objeto ActionEvent que permite que através do método getSource() seja recuperado o objeto que originou a chamada, e no nosso caso o botão cliclado.
Com o botão clicado, para distinguir qual botão foi clicado usaremos o texto que foi indicado na criação do botão através do método getText() e ai então, exibir um Alert. Nesse caso, customize qual ação deseja tomar. Um trecho desse método segue abaixo:
public void actionPerformed(ActionEvent evt) {
//Obtendo botão que disparou o evento
Button b = (Button) evt.getSource();
//Verificando pelo titulo qual botão é
if ( b.getText().equals("Bluetooth")) {
Alert a = new Alert("Selecionado", "Bluetooth", null, AlertType.INFO);
javax.microedition.lcdui.Display.getDisplay(this).setCurrent(a);
} else if ( b.getText().equals("Pesquisar")) {
Alert a = new Alert("Selecionado", "Pesquisar", null, AlertType.INFO);
javax.microedition.lcdui.Display.getDisplay(this).setCurrent(a);
}
//Continua comparações
//definindo focus
menu.setFocused(b);
}
Download e código completo
Para facilitar, todo o código do exemplo pode ser baixado em um ZIP, clicando AQUI, e dentro da pasta deployed é possível encontrar o JAR e JAD da aplicação para você ver o exemplo funcionando ou até instalar no seu celular.

Conclusão e comparação
Bom, quem já viu o outro exemplo e esse agora pode de cara perceber que esse tem um melhor acabamento e é muito mais facil de ser criado e customizado. Porém, o overhead causado pela quantidade de imagens necessárias e pela inclusão da biblioteca LWUIT. Para ver isso, basta comparar o tamanho das duas aplicações.
Mas, na minha opinião, se for um menu pequeno e com imagens não tão complexas, o uso vale a pena!! E além disso, você pode estudar e fazer o menu de uma forma que atenda melhor suas necessidades!

[]s
Neto

Nenhum comentário: