sábado, 1 de janeiro de 2011

LWUIT

Olá povo,

No primeiro post de 2011, falarei um pouquinho sobre o LWUIT (Lightweight UI Toolkit). Quem já desenvolveu alguma aplicação comercial com Java ME, sabe o como é complicado criar uma UI (User Interface) amigável com os componentes padrão. Os componentes LCDUI (Liquid Cristal Display UI) estão disponíveis no pacote javax.microedition.lcdui e trazem o benefício de manter a aparência da aplicação Java ME similar a uma aplicação nativa do aparelho. Porém, esses componentes são muito limitados dado o baixo poder de processamento dos dispositivos móveis na época em que esse framework foi concebido.

O LWUIT é um framework leve (como o próprio nome diz) e bastante poderoso para criação da interface gráfica de aplicações Java ME. Ele traz algumas similaridades com o Swing do Java SE e traz diversas funcionalidades interessantes como: uma boa quantidade de componentes; transições de tela; suporte a temas, estilos e fontes personalizadas; ajuste automático a diversos tamanhos de tela.

O LWUIT pode ser baixado separadamente a partir do site da Oracle. Clique aqui para baixar o ZIP com o JAR, documentação e exemplos de uso do framework.

Descompacte o conteúdo do arquivo em qualquer lugar da sua máquina e crie um novo projeto Java ME no Eclispe. Copie o arquivo LWUIT.jar (que está dentro do diretório lib) para seu projeto e adicione-o ao Build Path. Configure para que as classes do JAR do LWUIT sejam exportadas junto com o JAR da aplicação. Para fazer isso, clique com o botão direito sobre o projeto e clique em Properties. Ao abrir as opções do projeto, clique em Java Build Path no lado esquerdo, e na aba Order and Export, marque o checkbox do LWUIT.jar.

Uma vez com o projeto configurado, podemos executar o exemplo abaixo.


import java.io.IOException;

import javax.microedition.midlet.MIDlet;

import com.sun.lwuit.*;
import com.sun.lwuit.animations.CommonTransitions;
import com.sun.lwuit.events.*;
import com.sun.lwuit.layouts.*;
import com.sun.lwuit.plaf.UIManager;
import com.sun.lwuit.util.Resources;

public class TesteLWUIT_MIDlet extends MIDlet
// Interface genérica para tratar
// eventos dos componentes
implements ActionListener {

private Command cmdLista;
private Command cmdBack;
private Command cmdTabs;
private Command cmdExit;

private Button btn1;
private CheckBox checkbox;

private Form frmLista;
private Form frmPrincipal;
private Form frmTabs;

protected void startApp() {
iniciaLWUIT();
iniciaComandos();
iniciaFormPrincipal();
iniciaFormLista();
iniciaFormTabs();
}

protected void pauseApp() {
}

protected void destroyApp(boolean arg0){
notifyDestroyed();
}

private void iniciaLWUIT() {
// Inicializando o Display do LWUIT
Display.init(this);

try {
// Carrega o arquivo de recursos
Resources r = Resources.open("/LWUITtheme.res");

// Definindo o tema da aplicação
UIManager.getInstance().setThemeProps(
r.getTheme(r.getThemeResourceNames()[0]));

} catch (java.io.IOException e) {
}
}

// Iniciando comandos que são
// utilizados nos formulários
private void iniciaComandos() {
cmdLista = new Command("Lista");
cmdBack = new Command("Voltar");
cmdExit = new Command("Sair");
cmdTabs = new Command("Tabs");
}

// Criando tela principal
private void iniciaFormPrincipal() {
// Caixa de texto com capacidade de 20 caracteres
TextField txt = new TextField(20);

// Imagem para ser associada ao label
Image img = null;
Label imageLabel = null;

try {
// Carregando a imagem
img = Image.createImage("/duke.jpeg");
// Criando Label com a imagem
imageLabel = new Label(img);
// Define o texto do Label
imageLabel.setText("Label com Imagem");
// Define a posição do texto em relação a imagem
imageLabel.setTextPosition(Label.RIGHT);

} catch (IOException e) {
}

// Criando dois botões
btn1 = new Button("Botão 1");

// Definindo alinhamento do texto do botão
btn1.setAlignment(Label.CENTER);
// Informa que o botão pode
// receber foco com o direcional
btn1.setFocusable(true);

// Informa que a classe que
// tratará evento de clique
btn1.addActionListener(this);

// Criando RadioButtons
RadioButton rb1 = new RadioButton("Masculino");
RadioButton rb2 = new RadioButton("Feminino");
// Criando o RadioGrou e adicionando os botões
ButtonGroup group1 = new ButtonGroup();
group1.add(rb1);
group1.add(rb2);

// Checkbox
checkbox = new CheckBox("Não selecionado");
checkbox.addActionListener(this);

// Combobox
String[] content = {
"Vermelho", "Azul", "Verde", "Amarelo" };
ComboBox comboBox = new ComboBox(content);

// Inicializando e configurando o formulário
frmPrincipal = new Form();
frmPrincipal.setTitle("Formulário");
// Definindo o layout do formulário.
// BoxLayout adiciona os componentes um abaixo do
// outro (Y_AXIS) ou um ao lado do outro (X_AXIS)
frmPrincipal.setLayout(
new BoxLayout(BoxLayout.Y_AXIS));
// Adicionando componentes
frmPrincipal.addComponent(new Label("Nome:"));
frmPrincipal.addComponent(txt);
frmPrincipal.addComponent(imageLabel);
frmPrincipal.addComponent(btn1);
frmPrincipal.addComponent(rb1);
frmPrincipal.addComponent(rb2);
frmPrincipal.addComponent(comboBox);
frmPrincipal.addComponent(checkbox);
// Adicionando comandos
frmPrincipal.addCommand(cmdExit);
frmPrincipal.addCommand(cmdLista);
frmPrincipal.addCommand(cmdTabs);
// Definindo qual classe
// tratará eventos de comandos
frmPrincipal.addCommandListener(this);
// Definindo animação que será feita
// ao fechar e exibir o form
// Neste caso, Slide horizontal
frmPrincipal.setTransitionOutAnimator(
CommonTransitions.createSlide(
CommonTransitions.SLIDE_HORIZONTAL,
false, 200));
frmPrincipal.setTransitionInAnimator(
CommonTransitions.createSlide(
CommonTransitions.SLIDE_HORIZONTAL,
true, 200));
// Exibe o form
frmPrincipal.show();
}

// Inicializa uma tela de Lista
private void iniciaFormLista() {
String[] itens = {
"Opção 1", "Opção 2", "Opção 3",
"Opção 4", "Opção 5", "Opção 6",};
List lista = new List(itens);

frmLista = new Form("Exemplo Lista");
// Utilizando o BorderLayout
// Ele utiliza o conceito de NORTE,
// SUL, LESTE, OESTE e CENTRO
// Ao deixar um componente no centro
// ele ocupará o espaço restante da tela,
// como só tem um, ele preencherá toda a tela
frmLista.setLayout(new BorderLayout());
frmLista.addComponent(BorderLayout.CENTER, lista);
frmLista.addCommand(cmdBack);
frmLista.addCommandListener(this);
}

// Inicializa tela com abas
private void iniciaFormTabs() {
// Inicializa o painel de abas,
// mostrandos-as em cima
TabbedPane tabbedPane =
new TabbedPane(TabbedPane.TOP);
// Cria as abas adicionando um Label nas
// duas primeiras e um TextArea na terceira.
tabbedPane.addTab("Aba 1",
new Label("Label na primeira aba"));
tabbedPane.addTab("Aba 2", new Label("Aba 2"));
tabbedPane.addTab("Aba 3", new TextArea());

frmTabs = new Form("Exemplo Tabs");
frmTabs.setLayout(new BorderLayout());

frmTabs.addComponent(
BorderLayout.CENTER, tabbedPane);
frmTabs.addCommand(cmdBack);
frmTabs.addCommandListener(this);
}

// Tratando eventos das telas
public void actionPerformed(ActionEvent event) {
if (event.getSource() == cmdLista){
frmLista.show();

} else if (event.getSource().equals(cmdBack)){
frmPrincipal.show();

} else if (event.getSource() == btn1 ||
event.getSource() == cmdTabs){
frmTabs.show();

} else if (event.getSource() == checkbox){
if (checkbox.isSelected()) {
checkbox.setText("Selecionado");
} else {
checkbox.setText("Não selecionado");
}

} else if (event.getSource() == cmdExit){
destroyApp(true);
}
}
}


Abaixo temos um screenshot das telas da aplicação em execução:




Mas porque diabos a aplicação ficou com esse aspecto? E se eu quiser mudar o esquema de cores ou fontes ou qualquer outra coisa?

Se observarmos no método iniciaLWUIT, carregamos um arquivo de recursos chamado LWUITtheme.res. Esse arquivo já vem com o LWUIT e está localizado no diretório LWUIT_1_4\LWUITDemo\src. O LWUIT trabalha com um único arquivo de recursos que permite criar temas para definir as cores e fontes de cada elemento da UI de uma aplicação. Para criar e editar esses arquivos de recursos o LWUIT disponibiliza um editor visual que pode inclusive ser utilizado por designers. Esse editor está dentro do diretório util/ResourceEdit.exe (usuários não-windows podem executar o JAR diretamente que está no mesmo diretório). Abaixo temos um screenshot do editor, se quiser abrir o tema é só abrir o arquivo LWUITtheme.res com a ferramenta:



Alguns telefones podem não gostar do tamanho que o JAR pode ficar (em torno de 500KB) :) Para isso utilize o Proguard para obfuscar o código-fonte da aplicação e esse tamanho diminuirá sensivelmente.

4br4ç05,
nglauber

Nenhum comentário: