Você está na página 1de 45

Apostila de J2ME

verso 1.0
por Juliano Carniel e Clvis Teixeira
juliano@dainf.cefetpr.br
clv@dainf.cefetpr.br
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
ndie
ntroduo 1
Entendendo J2ME 2
Segurana 3
Tecnologias 4
Diferena entre MDP 1.0 e 2.0 4
A!"#s $ %
Criando projetos, Compilando e Executando 5
Obfuscator 8
Ciclo de vida de uma MDlet 8
nterface 9
Commands 11
TextBox 13
Tickers 13
Forms 14
tem 14
Lists 16
magens 17
Alerts 18
Conexes 18
SMS via Servidor 20
Armazenameto em celulares 20
Canvas 22
Codificando 22
Codigos Exemplos 23
ExemploCommandsandTicker 23
ExemploListandAlert 25
ExemploTextBox 27
ExemploForm1 29
ExemploGauge 31
ExemploConnectionmage 34
ExemploHttpConnection 37
ExemploCanvas 40
Referncias Bibliogrficas 42
Copyright 43
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
1
Apostila de J2ME
- "ntrodu&'o(
Comecemos com uma pergunta bsica porm no menos importante. O que vem
a ser esse J2ME? E para que serve?
Java 2 Micro Edition uma AP Java voltada para micro aplicativos que rodam
em micro processadores assim como os dos celulares.
Neste Tutorial vamos tratar da Tecnologia J2ME MDP 1.0 voltada para
aplicaes grficas porm no vamos tratar de jogos aqui, embora aps a leitura deste,
voc pode ter um embasamento para comear a desenvolver algo na rea. As aplicaes
criadas usando-se MDP so chamadas MDlets (assim como Servlets e Applets).
Usamos os programas:
- Wireless Tollkit que um software gratuito feito pela Sun para simplificar o ciclo
de desenvolvimento do J2ME o qual pode ser encontrado em
http://wireless.java.sun.com/allsoftware/ ( necessrio que voc j tenha o j2sdk instalado
http://java.sun.com/j2se/1.4.1/download.html), voc ainda pode baixar outros emuladores
encontrados na mesma pagina do Wireless Toolkit para posteriores testes.
- E o editor GEL que free, e um timo editor facilitando muito na edio com
auto-complete de mtodos e muitas outras facilidades que este programa prov, e pode
ser encontrado em www.gexperts.com
Caso voc j tenha algum outro programa como o Eclipse por exemplo, pode-se
usa-lo tambm fazendo as devidas modificaes.
Como j citado trabalhamos com MDP 1.0, e alguns podem se perguntar por que
no a 2.0? Todos celulares existentes hoje, ou a grande maioria, usa a tecnologia 1.0
ento ainda no se justifica o uso da verso 2.0, e iremos demonstrar posteriormente
algumas diferenas, embora no sejam muitas, e nem gritantes.
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
2
- Entendendo J2ME
J2ME dividido em configurations, profiles e AP's opcionais.
Para entendermos melhor, pensemos da seguinte maneira, Profiles so mais
especficos que configurations, e fazendo analogia a um velho exemplo temos uma
abstrao sobre o que um carro e como ele fabricado (configuration) e como um Ford
fabricado (profile), mais tecnicamente falando profile baseado em configuration e
ainda acima dos profiles esto as AP's que na nossa analogia seria um modelo
especfico da Ford.
Existem dois "configurations", um configuration o CLDC (Connected, Limited
Device Configuration), que rege as configuraes para aparelhos bem pequenos como
celulares ou PDA's, o qual fica acima das diretrizes J2ME juntamente com CDC
(Connected Device Configuration) o que rege as configuraes para aparelhos um pouco
maiores, mas mesmo assim pequenos.
Podem haver vrios Profiles vamos citar dois aqui os quais so os mais
importantes para este estudo, MDP (Mobile nformation Device Profile) e tambm o
PDAP (Personal Digital Assistant Profile) e ambos esto acima do CLDC.
CLDC como j vimos rege as configuraes para aparelhos extremamente
pequenos, ele foi desenvolvido para dispositivos de 160KB 512KB com memria valida
para Java. Voc no leu errado e nem ns trocamos unidades de medidas, a memria
est realmente certa, o que nos faz pensar muito em termos de aplicaes que podem
rodar neles e nos traz de volta a certas programaes para DOS no que diz respeito
memria. E falando em memria relevemos tambm o processamento que muito fraco,
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
3
mas muito mesmo no mais que 10Mhz e isto se tratando de aparelhos tops de linha (at
a composio desta materia), o que nos faz analisar melhor cdigos e mtodos usados,
os quais dispendem de muito processamento e uso de memria. E tambm a conexo
lenta, tipicamente de 9.600bps.
MDP tem as seguintes caractersticas:
-128kB de memria no-voltil para JAVA.
-32KB de memria voltil para tempo de execuo.
-8KB de memria no-voltil de para armazenamento de dados.
-uma tela de pelo menos 96x54 pixels (aqui j cai por terra a propaganda de
muitos celulares, os quais dizem ter uma tela ampla de 96x54, o que o mnimo
necessrio).
-Capacidade de entrada de dados seja por teclado (do celular), teclado externo
ou mesmo Touch-screen.
-Possibilidade de enviar e receber dados em conexo.
- )eguran&a
Uma pergunta freqentemente feita : Agora com programas rodando nos
celulares no iremos ter problemas de vrus, ou programas maliciosos? A resposta no,
pois o Java no tem acesso a AP do celular em si, ou seja, ele no poder acessar
funes especificas do celular como, por exemplo, a agenda telefnica, sendo assim no
podero ser apagados ou modificados seus dados, a no ser que o fabricante lhe
disponibilize esta AP, como o caso dos jogos nos celulares, cada fabricante
disponibiliza uma AP especfica para os jogos, podendo assim aproveitar melhor o
desempenho do aparelho, porm cai por terra a forte caracterstica de vida do JAVA, a
(WORA) "Write Once, Run Anywhere!", apesar de ser mais seguro, perde-se um pouco e
funcionalidade.
A maquina virtual tem um espao independente de memria, e no pode acessar
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
4
a memria correspondente s aplicaes nativas do celular.
Outro ponto importante que no permitida a carga de classes definidas pelo
usurio, ou seja, o usurio no tem acesso a outras funes que no seja as da VM, o
que aumenta a segurana, porm restringe um pouco o desenvolvimento.
- Tenologias *ireless
Muitas pessoas ainda tem dvidas sobre as diferentes tecnologias de celulares
existentes. Vamos tentar defini-las e diferencia-las em poucas palavras, sendo que este
no o enfoque principal deste Tutorial.

- TDMA: (time division multiple access, ou acesso mltiplo por diviso do tempo),
ou seja, ele no diferencia voz e dados ento para navegar na internet(dados) voc paga
o mesmo preo que pagaria por fazer uma ligao de voz. Quem tem algum celular tdma
sabe o quo caro e lento isso. Somente para estabelecer a conexo leva-se 8
segundos e a transferncia de dados da-se a 9.600bps.

- CDMA: (code division multiple access, ou acesso mltiplo por diviso de
cdigos), ou seja, separado voz de dados, e tanto esta tecnologia quando a gsm so
conexo 100% ativa, ou seja, no existe este delay de conexo voc requisita uma
informao e ela vem diretamente. Alm de a taxa de transferncia que maior
chegando a 256Kbps usando CDMA 1xRTT, que o que esta em vigor.

- GSM: (global system for communication, ou sistema global de comunicao), ou
seja, tem as mesmas caractersticas da tecnologia CDMA, porm opera usando GPRS.
Caso haja maior interesse nas tecnologias de transmisso e na evoluo e tudo
mais que diz respeito recomendo estes sites http://www.sit.com.br/SeparataTELCO50.htm
e http://idgnow.terra.com.br/idgnow/telecom/2002/09/0043 .
+i,eren&a entre M"+! -.0 e 2.0
Existem algumas diferenas entre as verses, como todos sabemos a cada
verso mais nova sempre incrementado mais funes. Alm desses mtodos a mais, e
algumas facilidades maiores da 2.0 como classes para jogos, e tratamento de sons,
temos a diferena na comunicao de dados que o mais interessante aqui como, por
exemplo, as conexes so feitas atravs do protocolo http que no caso inseguro no
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
5
envio de informaes, j na 2.0 est implementado o https (ssl) conexo com criptografia
que j conhecida de todos.
Aqui listamos os Packages disponveis para as verses.
java.lang
java.lang.ref (somente 1.1)
java.io
java.util
javax.microedition.io
javax.microedition.lcdui
javax.microedition.lcdui.game (somente na 2.0)
javax.microedition.media (somente na 2.0)
javax.microedition.media.control (somente na 2.0)
javax.microedition.midlet
javax.microedition.rms
javax.microedition.pki (somente na 2.0)
Opcionalmente, fabricantes podem fornecer AP's JAVA para acesso a partes
especificas de cada aparelho.
Com relao segurana a MDP 2.0 traz bastante recursos nessa parte, e j se
aproxima mais do J2SE, com Permissions Types, Protection Domains baseados em P's
e PK's.
- A!"#s
A MDP 1.0 no possui suporte a ponto flutuante, ou seja, se desejas trabalhar
com contas, e valores reais ters que manuse-los em cdigo mesmo. A verso 1.1 do
CLDC j possui suporte a ponto flutuante, porm mesmo com a verso 1.0 voc pode
baixar programas especficos pra isso como esse programa encontrado em
http://home.rochester.rr.com/ohommes/MathFP .
Voc tem ainda outras restries como:
Sem user classLoading
Sem finalizao de objetos (finallize() de java.lang.Object)
Garbage collector existe, porm no executa mtodo automtico.
Sem RM e sem JN
Sem mtodos nativos, a no ser os fornecidos pela JVM nativa.
MultiThreading (sem interrupt(), pause(), resume() e stop())
Sem thread groups e thread Deamons
- Criando pro/etos0 Co1pilando e Exeutando
Bom depois de muita teoria, a qual nos deu um embasamento melhor para
sabermos o que estamos fazendo, vamos a uma parte mais prtica, e a mais esperada
por todos.
O processo de desenvolvimento de MDlet's um pouco mais complexo do que
de outros programas feitos em JAVA, pois feito segundo estes passos:
Editar cdigo fonte;
Compilar;
Pr-Verificar;
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
6
Empacotar;
Testar e/ou nstalar;
Depois de tudo instalado corretamente, devemos primeiramente abrir o Wireless
ToolKit e criar um Projeto, para isso clique em New Project.
Depois em Project Name defina o nome do seu projeto, e logo abaixo o nome da
classe de sua midlet que deve ser igual ao nome do projeto.
Feito isso ele ter criado vrios diretrios dentro de
path_WTK/apps/Sua_Aplicacao/, para cada aplicao criado uma rvore de diretrios
conforme ilustrado abaixo.
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
7
Em seguida abrir uma tela que contm informaes sobre a sua aplicao,
aconselho a no mudar o que est l, pois por esse arquivo que o celular reconhecer
antes de ser baixado, se ele apto a rodar ou no seu programa, a nica coisa que
poderias mudar seria o Vendor Name, o qual voc pode colocar o nome de sua empresa,
ou o que desejares. Se vocs verificarem a ltima aba desta tela (aba MDlets), tem um
link para uma figura .png, que o icone que aparecer no celular de sua aplicao voc
pode modific-lo colocando o nome de uma figura personalizada, apenas lembre-se que
a figura deve ficar no devido diretrio (path_WTK/apps/Sua_Aplicacao/res), e sempre
para qualquer aplicao deve-se por dentro do diretrio /res.
Existem dois botes que sero muito utilizados por nos, BULD, e RUN, os quais
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
8
so auto-explicativos.
Aps a criao do projeto, estamos aptos, e finalmente, a criar nossos cdigos.
23,usator
Como vimos dispositivos celulares possuem memria muito reduzida, e quanto
menor sua aplicao for, melhor ser para o celular. Para isso usamos o Obfuscator que
usado para diminuir o tamanho dos arquivos eliminando redundncia e tambm para
evitar engenharia reversa.
Este programa, renomeia classes, variveis e mtodos para nomes mais
compactos, removem classes, mtodos no usados e ainda inserem dados ilegais ou
questionveis para confundir Descompiladores.
Para criar um pacote obfuscado voc precisa de algum programa Obfuscator, um
bom programa, o Retroguard, pode ser encontrado em www.retrologic.com, depois de
baixado voc deve copiar o arquivo retroguard.jar dentro do diretrio bin do
wirelessToolkit. (Ex: c:\WTK104\bin)
- Cilo de 4ida de u1a M"+let
O Aplication Manager (AM) de cada dispositivo quem vai controlar os aplicativos
a serem instalados, onde e como sero armazenados e como sero executados. As
classes de cada aplicativo esto em um arquivo JAR, o qual vem acompanhado de um
descritor JAD, que ter todas as informaes as quais j vimos anteriormente.
Assim que a MDlet invocada, o AM invoca o mtodo startApp(), o qual coloca a
midlet no estado Active. Enquanto ela estiver executando o AM pode pausar ela
invocando o mtodo pauseApp() no caso de uma chamada sendo recebida, ou SMS
chegando. A aplicao pode pausar a si mesma, bastando invocar notifyPaused(). Assim
como a AM pode pausar a aplicao e esta a si mesma, ocorre o mesmo com o
DestroyApp() que invocado pela AM para fechar a aplicao ou at mesmo pode ser
fechada atravs da prpria aplicao invocando o notifyDestroyed().
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
9
- "nter,ae
As MDlets devem poder ser executadas em qualquer dispositivo sem alteraes,
contendo a VM, porm isso torna-se bastante difcil na parte de nterface com usurio,
pois dispositivos variam de tamanho de tela, cores, teclados, touch-Screens e outros
aspectos.
As aplicaes so desenvolvidas com uma certa abstrao de tela, pois os
comandos e inserso de dados so feitos atravs dos botes do celular, e isto no
sabemos previamente. As aplicaes descobrem isto em Runtime e se comportam de
maneira apropriada a cada celular. J no desenvolvimento de jogos a aplicao bem
mais especfica, pois o desenvolvedor precisa conhecer o dispositivo previamente para
melhor aproveitamento de recursos, como disposio em tela por exemplo.
A tela do dispositivo representada por uma instncia da classe Display, a qual
obtida pelo mtodo getDisplay(), geralmente contida no mtodo startApp(), pois o mtodo
getDisplay(), somente fica disponvel aps o inicio da Aplicao (startApp()). Nessa
instancia de Display so inseridos heranas de Displayable.
public void startApp()
{
Display d = Display.getDisplay(this);
...
}
Na tela so mostrados componentes, objetos j instanciados, os quais so
chamados pelo mtodo setCurrent() o qual seta o objeto que ser mostrado.
O ciclo bsico de uma MDlet pode ser definido por:
Mostrar um Displayable;
Esperar por Ao do Usurio;
Decidir qual Displyable mostrar em seguida;
Repetir;
As aes do usurio so gerenciadas por comandos (commands), os quais so
adicionados a componentes visuais. E tambm temos as classes Screen e Canvas as
quais podemos dividir em duas classes:
High-level AP's que engloba a classe Screen e suas heranas, pois so classificados
como objetos de nterface.
Low-level AP's que engloba a classe Canvas e suas heranas, as quais proporcionam
uma rea livre para grficos.
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
10

- Co11ands
Os commands com vimos, so usados para interao do usurio com a
aplicao. Sua aplicao bsica na troca de Displayables, os quais so acionados por
elementos reais do dispositivo, que podem ser: softkeys, itens de menu, botes e
dispositivos de acionamento.
Esses commands so entidades abstratas e podem ser adicionados
arbitrariamente para cada elemento Screen ou Canvas.
Os commands tem trs propriedades:
Label: texto mostrado ao usurio na interface;
Type: tipo do comando;
Priority: prioridade dos comandos que so utilizados para mostrar os comandos mais
utilizados com maior facilidade.
Command(String abel! int "ype! int #riority);
$%&
ComandoSair = ne' Command((Sair)! Command.$*+"! ,);
As aes dos commands so totalmente dependente do cdigo, ou seja, voc
ter que implementar a ao de cada command selecionado, os quais ficaro dentro de
um mtodo chamado commandAction, que vem como herana quando a MDlet herda
CommandListener. Existem os mtodos addCommand(Command) e removeCommand
(Command), os quais so auto-explicativos. Os commands so geralmente relacionados
a SoftKeys ou SoftButtons, que so botes existentes nos celulares os quais so usados
para menus, e navegao em geral, sem uma funo nica. Geralmente possui-se dois
botes de SoftKeys, porm isso no significa que voc precisa s ter dois commands
sendo implementados, pois se houver mais commands que botes eles so agrupados e
aberto um menu. Para isso que serve a prioridade setada nos botes, ou seja, a
prioridade 0 (mais prioritrio) indica que esse command deve ser mostrado nas softKeys,
ou em primeiro lugar no menu.
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
11
O tratamento dos commands feito com o conceito de Listeners, ou seja,
comandos so adicionados a Displayables, cada displayable pode possuir um
CommandListener o qual invocado assim que um command acionado.
public void setCommandistener(Commandistener)
Exemplo:
"e%t-o% t. = ne' "e%t-o%(("e%to)! ()! .,!"e%t/ield.A01);
t..setCommandistener(this);
t..addCommand(ComandoSair); 22comando 3eito acima
Mtodo commandAction
public void commandAction(Command c! Displayable d)
{
i3 (c==comando.)
{
...
}
}
- Text5ox
um componente bsico que serve para entrada de texto(string) em celulares.
Todos sabemos o quo entediante a entrada de dados em celulares, e por isso temos
que aprimorar essa tcnica e manter o bom padro de uma MDlet, e de qualquer outro
programa que deixar o usurio feliz e menos cansado e entediado.
O construtor de um textBox :
public TextBoxStrin! titulo" Strin! texto" int tam#Max" int con$traint$%&
onde:
Titulo mostrado no topo da tela.
Texto mostrado dentro do textbox, como string inicial.
tam_Max tamanho mximo que ser alcanado pelo textBox.
Constraints so as constantes da classe TextField, as quais veremos logo abaixo.
Exemplos:
TextBox t1 = new TextBox(Nome: , , 30, TextField.ANY);
TextBox t2 = new TextBox(Nome: , , 20, TextField.ANY |
TextField.A!!"#$%);
- Ti6ers
Ticker nada mais que um texto que corre no topo da tela, semelhante as tickers
de mercados de aes, e semelhante ao <marquee> de html. O recurso de Ticker serve
para algum texto informativo que possa ser importante, ficar lembrando toda hora, ou algo
de enfeite que voc queira colocar. Mas lembre-se, a tela do celular j pequena para
sua aplicao, e o ticker tomara mais uma linha para si, a qual no poder ser usada.
Sua criao simples.
22 Displayable d = ...
"ic4er tic4er = ne' "ic4er(($sta mensagem deve passar na tela));
d.set"ic4er(tic4er);
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
12
E os mtodos para manuseio dessas Tickers no poderiam ser outros seno:
public void set"ic4er("ic4er tic4er)
public "ic4er get"ic4er
- 7or1s
Form uma herana de Screen e Displayable, o qual pode conter um nmero
arbitrrio de controles de interface chamados 'ten$( Um form tem a mesma funo de um
Container em AWT, mas com as limitaes da MDlet claro, ele serve para poder-se
colocar mais de um componente na tela. Apesar de haver rolagem automtica quando
todos os objetos no cabem na tela, cuidado para no deixar um form muito grande com
muitos componentes, pois a rolagem dos forms tende a ser confuso nos dispositivos, pois
cada um implementa isso da sua maneira, e por isso no deve se tornar uma prtica
corriqueira, alm de tornar seu aplicativo esteticamente mal feito, pois o usurio muitas
vezes no ir saber se h mais objetos a serem preenchidos.
Para criarmos um form temos duas sobrecargas:
public Form(String Titulo);
public Form(String Titulo, Item[] itens);
Como vimos os forms recebem itens os quais so divididos em diversos tipos
cada um com sua finalidade.
Os itens podem ser adicionados e removidos mesmo com os forms sendo
mostrados. Os mtodos de trabalho com os forms so:
append(tem item);
set(int ndice, tem item);
insert(int ndice, tem item);
delete(int ndice);
Lembre-se que o mtodo append adiciona um novo item no final da lista, e o
mtodo in$ert adiciona um item no ndice indicado movendo os outros existentes para
baixo.
- "te1
Como j foi falado existem vrios tipos de itens, e cada um com sua determinada
funo. Esses diversos tipos de itens estendem da classe tem. Esses itens so inseridos
em forms, eles podem ou no ter um Label, podem ou no ser mostrados, eles podem ter
comandos associados a eles.
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
13
Vamos relata-los aqui.
A partir de agora vamos usar o mesmo form que criaremos agora, para todos os
exemplos abaixo:
Fo&m 'o&m = new Fo&m(Fo&m de te(te);
StringItem nada mais que um simples texto.
Para este tem, existem os mtodos de manipulao: getLabel(), setLabel(),
getText(), setText();
Strin!'tem)*abel: +"+Text+%&
,x: String+tem str+tem = ne' String+tem((0ome&
)!)5uliano));
3orm.append(str+tem);
TextField - uma string editvel, ou melhor exemplificando um campo para
preencher.
Para este item existem os mtodos de manipulao: getString(); setString();
TextField(String Label, String Text, int TamMax, int Constraints)
,x: "e%t/ield t3 = ne' "e%t/ield((Digite seu 0ome& )! ()!
6,! "e%t/ield.A01);
3orm.append(t3);
As constraints so as mesmas do TextBox (ANY, PASSWORD, EMALADDR,
NUMERC, PHONENUMBER, URL).
ImageItem mostra a instncia de uma magem dentro de um form, ou seja, voc
precisa j de um objeto mage. Este item possui um label, um texto alternativo e pode
ser posicionado segundo um layout.
magetem(String Label, mage imagem, int Layout, String texto_alt);
Os layouts so constantes da classe, e podem ser: LAYOUT_DEFAULT,
LAYOUT_LEFT, LAYOUT_CENTER, LAYOUT_RGHT,
*A./0T#N,1*'N,#B,2/3,4" *A./0T#N,1*'N,#A2T,34).
4$omente exi$tente$ no M'DP 5(6
,x: )m*+e im+ = new )m*+e.,&e*te)m*+e(-'oto..n+);
)m*+e)tem im+)tem = new )m*+e)tem(Foto, im+,
)m*+e)tem./AY#0T1%2FA0/T, Alt Text);
'o&m.*..end(im+)tem);
DateField - uma interface usada para datas, horas ou ambos, como ir aparecer
por conta do Celular e o programador no tem controle sobre isso. No construtor deve
ser especificado a Label e o tipo de dado, que pode ser:
- Date2ield(DAT,
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
14
- Date2ield(T'M,
- Date2ield(DAT,#T'M,
public Date2ieldStrin! *abel" int modo%&
,x: %*teField d*t* = new %*teField(%*t*: , %*teField.%AT2 );
Gauges - uma representao grfica de um valor inteiro, e como ele ser mostrado
depende da implementao de cada aparelho. Existem dois tipos de gauges, o
interativo, que permite a ao do usurio sobre seu valor, e No interativo controlado
somente pelo programa. Os valores podem ser alterados em tempo de execuo,
pelos comandos getMaxValue(), setMaxValue(); setValue(), getValue().
public Gau!eStrin! *abel" boolean 'nterati7o" int ValorMaximo" int Valor'nicial%&
,x: 3*4+e + = new 3*4+e(3*4+e )nte&*ti5o, t&4e, 20, 1);
ChoiceGroup - uma lista de escolhas semelhante a List, ambos implementam a
interface Choice. Os tipo de listas so Exclusive e Multiple, porm no tem o tipo
mplicit. J na MDP 2.0 implementado o tipo POPUP, que deixa a lista semelhante a
um menu DropDown.
public Choice7roup(String label! int tipo)
public Choice7roup(String label! int tipo! String89 elementos!
+mage89 imagens)
Eventos de tens
Os tens possuem eventos de alterao de Estado, que podem ser manejados para.
Aplicao pode tratar eventos de alterao de estado em tens
nterface temStateListener
mtodo public void itemStateChanged(+tem item)
Registra-se o listener com o mtodo:
set+temStateistener(+temStateistener listener)
- 8ists
Como o prprio nome diz so listas, as quais permitem ao usurio selecionar
itens (elements) de uma lista. Esses elementos podem ser representados tanto por
Strings quanto por magens.
Existem trs tipos de listas, mplicit, Exclusive e Multiple. mplicit deixa voc
escolher uma opo e clicar no boto padro de seleo ou em um command que voc
adicionar, Exclusive, que lembra uma lista de Radio, permite somente a seleo de uma
opo e para seleciona-la deve-se usar um boto com um Command setado. E ainda tem
a list Multiple, que funciona como uma CheckList j conhecida de todos, que nos permite
selecionar vrias opes.
Quando selecionado um item em uma lista mplicit, o mtodo CommandAction
chamado, sendo que para esta List j foi anteriormente adicionando um
CommandListener.
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
15
Existem duas sobrecargas para este construtor, no qual voc pode iniciar os
Arrays de elementos e de magens ou no. O array de elementos, se utilizado, no
poder ser nulo, mas poder conter elementos nulos, os quais aparecero em branco na
tela.
public ist(String titulo! int tipo)
public ist(String titulo! int tipo! String89 elementos! +mage89
imagens)
Quando uma lista tornar-se grande demais para a tela, ser criado uma rolagem,
a qual no cabe a ns implementa-la, ela por conta da VM.
Cada elemento da list possui um ndice. Esse ndice inicia em 0. Para editar uma
list, existem alguns mtodos que valem a pena ser comentados aqui. Que so:
set( altera o elemento do qual o ndice foi fornecido;
insert( insere um elemento em uma posio indicada por um ndice. Se este ndice
estiver no meio da lista, ele fora os outros elementos uma posio frente;
Append( inclui um elemento ao final da lista;
delete( remove o elemento indicado pelo ndice;
EX:
public void set(int indice! String elemento! +mage imagem);
public void insert(int indice! String elemento! +mage imagem);
public int append(String elemento! +mage imagem);
public void delete(int indice);
Dois mtodos bastante utilizados que valem a pena ser comentados so:
public boolean isSelected(int indice) que me diz se o ndice esta selecionado
atualmente.
public int getSelectedIndex() que me retorna o ndice que foi escolhido, somente
para listas mplicit e Exclusive.

- "1agens
A especificao de MDP determina que a implementao dever ser capaz de
manipular magens PNG, o que no ocorre em todos os celulares. Alguns trabalham com
JPG, outros com GF, BMP, e at mesmo PNG sem compactao, porm muito raro
voc conseguir encontrar a especificao de cada aparelho para isso, o que torna muito
difcil a programao com imagens, quando no usado o padro.
public static +mage create+mage(String nome)
public static +mage create+mage(byte89 dados! int o33set! int tamanho)
O primeiro construtor busca o arquivo indicado pelo nome na pasta /res, de sua
aplicao no caso de uso do emulador, quando ele compilado e empacotado, a imagem
empacotada junto com o programa. O segundo construtor obtm a imagem de um
Arrray de Bytes, partindo da posio offset, at o tamanho indicado. Essas imagens
podem ser Mutveis ou mutveis. As mutveis podem ser modificadas pelo Objeto
Graphics, obtido pelo mtodo getGraphics(). Porm, esses dois construtores citados
acima geram imagens imutveis. Para se criar imagens mutveis deve-se usar o seguinte
mtodo.
public static +mage create+mage(int largura! int altura)
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
16
Lembre-se que as imagens passadas para Alerts, ChoiceGroups, mgetems, ou
Lists devem ser mutveis. magens mutveis podem ser criadas a partir de outras
imagens Mutveis.
public static +mage create+mage(+mage imagem)
Somente um comentrio parte. magens em MDP 2.0 podem ser criadas
partir de pores de outras imagens j existentes.
public static +mage create+mage(+mage image! int %! int y! int
largura! int altura! int trans3ormacao)
- Alerts
Um alert nada mais que uma mensagem informativa ao usurio, tem a mesma
idia de um alert de javascript, ou VB, ou qualquer outra linguagem, ou seja, ele
basicamente uma "telinha que mostra uma mensagem e logo depois sai da tela.
Esses alerts podem ser tanto Timed Alerts, ou Modal Alert. No Timed Alert, voc
pode setar um tempo ou no o qual receber o tempo padro do aparelho. E o alerta
modal que aparece e fica esperando uma interveno do usurio, e possui vrios tipos,
como Alarm, Confirmation, Error, nfo, Warning, cada qual com seu cone e som, os quais
tambm podem ser setados pelo desenvolvedor.
public Alert()
public Alert(String titulo! String te%to! +mage icone! Alert"ype
tipo)
48ual9uer um ou todo$ o$ par:metro$ do $e!undo con$trutor podem $er nulo$(
Alerts so criados com um tempo default para desaparecer, tempo qual
implementado na VM, e pode ser obtido por getDefaultTimeout(), e tambm configurado
por setTimeout(). Quando criamos um Timed Alert, podemos transforma-lo em modal
adicionando ao parmetro AlertType para Alert.FOREVER.
Ex:
Alert alerta;
alerta = ne' Alert((Alerta)!)Acesso n:o autori;ado.)! null! null);
alerta.set"imeout(<,,,);22 timeout para < segundos
O comportamento padro de um Alert mostar a prxima tela setada, se usado o
mtodo $etCurrentatual" pr;ximo%" ou ele ir voltar para a tela atual se for usado,
setCurrent(Alert).

- Conex9es
Sistemas mveis geralmente oferecem acesso a dados via conexes OTA(Over
The Air), porm essas conexes ainda so lentas, pouco confiveis e intermitentes, o
que nos dificulta um pouco essa transmisso de dados, e na pior das hipteses entedia o
usurio, este por estar j acostumado com uma conexo rpida e confivel.
A MDP possui mecanismos genricos para acesso a rede, as quais so definidas
pela CLDC que bem flexvel. Para isso ela usa o Package javax.microedition.io e
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
17
baseada na interface Connection. O link real entre a interface Connection feito atravs
da classe javax.microedition.io.Connector, que funciona passando-se uma string de
conexo para um mtodo esttico de Connector e recebe uma Connection com
resultado.
A conexo na MDP 1.0 feita por HTTP, atravs de HttpConnection, porm
algumas implementaes particulares de celulares podem oferecer HttpsConnection,
SocketConnection entre outros. J na MPD 2.0 a obrigatoriedade passada para a
implementao do HttpsConnection. Ambos os mtodos tratam das particularidades do
protocolo Http como Headers, mtodos e outros(RFC 2616).
O Http trabalha com o processo de response/request incluindo Headers no
processo. Os parmetros passados na url so codificados antes da transmisso o que
garante integridade da informao e padronizao, para isso utiliza-se de URLEncoder,
que transforma espaos em sinais de +, a...z, A...Z, 0...9, ponto(.), Hfen(-), Asterisco(*) e
Underscore(_) so mantidos, e todo qualquer outro caractere convertido em %xy, onde
xy o valor Hexadecimal que representa os 8 bits menos significativos do caractere.
Revisando um pouco Http, temos os mtodos GET, POST e HEAD, onde GET e
POST buscam paginas, GET enviando parmetros na URL, enquanto POST envia os
parmetro no header, e o HEAD que idntico ao GET, porm o servidor s responde
com Headers.
A conexo GET funciona, passando-se uma URL para o mtodo open() da classe
connector, da qual voc ir receber o resultado como um HttpConnection ou um
nputConnection (trataremos disso depois), ento voc dever obter os streams de
conexo nputStream e OutputStream, e ento ler os dados que foram retornados para
voc do Servidor e trat-los conforme o que voc precisa, e para isso voc deve
antecipadamente conhecer o formato de retorno da informao vinda do servidor.
Ex: String url = (servidor.com.br2sua#agina.=sp); a9ui pode $er
9ual9uer pa!ina de 9ual9uer exten$<o" inclu$i7e Ser7let$ 9ue $<o !eralmente utili=ado$
como re$po$ta para M'Dlet$%
+nputConnection ic = (+nputConnection) Connector.open(url);
+nputStream is = ic.open+nputStream();
>>a9ui 7ai todo o proce$$o de leitura Veja no$ ,xemplo$%" 9ue $er? !uardado em
um arra@ de b@te$ dependendo do tipo de dado 9ue 7ocA e$pera do $er7idor" n<o
e$9ueBa 9ue $e 7ocA e$pera um dado 9ue n<o $eja puro texto depoi$ ter? 9ue con7erte-
lo para $eu e$tado ori!inal" e ca$o 7ocA e$teja e$perando Strin!$ como re$po$ta" u$e
Strin!BuCCer(
ic.close();
Sempre que voc estabelece uma conexo Http, aconselhvel que verifique o
retorno dos Headers para saber se o retorno est ok, atravs de
HttpConnection.HTTP_OK.
Ex:
int status = >.;
status = con.get?esponseCode();
i3 (status == @ttpConnection.@""#ABC)
{
22 processa resultado
}
+ias(
Sempre que for fazer uma conexo tenha uma thread separada para isso.
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
18
- Acesso sempre toma tempo e pode ser demorado.
- Mantenha algum tipo de indicao de progresso para a interface com o usurio.
Use GET ao invs de POST
- Mais simples e sem a preocupao com request headers
No use URLs hard-coded
- Mantenha em application descriptors, o que permite alterar a URL sem
recompilao
Tenha certeza de que as excees so tratadas adequadamente
Redes wireless no so muito confiveis, prepare-se para o pior.
Capture todas as excees e proceda de forma razovel, com mensagens e indicaes.
Libere memria e recursos assim que possvel
Em dispositivos portteis, tais recursos so muito escassos
- )M) via servidor
O Suporte a SMS s dado usando-se MDP 2.0 o qual ainda no est em vigor
em nenhum celular no Brasil, ou ao menos a grande maioria usa MDP1.0 (at esta
publicao). Sendo assim, ser muito difcil voc conseguir desenvolver alguma aplicao
com relao a isso, sendo que com a mipd1.0 j em vigor esta sendo bem difcil de se
encontrar material e uma tecnologia que a comunidade esta comeando a interessar-se
agora.
Bom em alguns fruns j houve algumas perguntas sobre esse tpico e por isso
vou comentar aqui algumas coisas. Bom, algum pediu como fazer para mandar sms de
servidores remotos, o que necessrio um contrato com uma operadora a qual lhe
fornecer passagem livre do seu P pela rede dela, lhe permitindo o envio dessas
mensagens nada tem o que ver com a tecnologia J2ME. E obviamente no h a
necessidade de se construir uma aplicao pra isso sendo que os celulares j possuem
isso nativo.
- Ar1a:ena1ento e1 elulares ;<eord)tores=
A persistncia em celulares tratada com RecordStores que so conjuntos de
registros e instncias de javax.microedition.rms.ecordStore!
Cada recordStore identificado por um nome que deve ser nico, sua criao
feita de forma simples e bem sugestiva, da seguinte forma:
ecordStore.openecordStore(!"ome#ual$uer%, true);
O parmetro boolean da chamada do mtodo indica que se true o RecordStore
ser aberta e se no existir ser criada. O Cal$e apenas abre uma RecordStore existente.
Lembre-se tambm que sempre que for manusear um RecordStore voc precisa usar
tr&'( catc)'(" pois estas operaes geram excees como: RecordStoreException,
RecordStoreFullException, RecordStoreNotFoundException.
Assim como abrimos os recordStores temos que fecha-los, e sempre que abrir
um recordStore, e assim que ele no for mais necessrio, fecha-lo, pois lembremos que
trabalhamos com uma memria bem reduzida, no esquea que o mtodo pauseApp,
tambm deve fechar os recordStores. O mtodo para fechar o recordStore nada mais
que:
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
19
Bb=eto?ecordStore.close?ecordStore();
A estrutura de Armazenamento do um RecordStore bem simplria, possui
apenas um id e um array de Bytes como local para armazenagem de dados. Se voc est
acostumado com banco de dados, e com uma estrutura de linhas e colunas, esquea! Se
quiseres guardar mais que uma informao no array de Bytes, ters que trabalhar com
este array, colocando algum caractere de controle para seu armazenamento (Ex: Nome |
Telefone). Somente como exemplo, ns trabalhamos com uma aplicao onde era
preciso guardar um nome, e uma fotografia, e ento colocvamos o nome
+"carc_de_Controle+Foto[ ], e ento na hora de lista essas fotos tnhamos que trabalhar
com cada registro percorrendo o array inteiro para primeiro listar o nome e depois a foto,
a qual tinhamos que pegar o array e ento criar um mage, e ento colocvamos em um
magetem.
Cada registro pode ser lido ou modificado, segundo seu D, que retornado a
cada insero.
public byte89 get?ecord(int record+D)
Nos retorna um array de bytes para podermos trabalhar com ele.
Para deletar records, usamos o mtodo:
public void delete?ecord(int +D)
Quando deletamos um record, o seu id, continua existindo, no sendo
reorganizada a lista, ou seja, quando voc quiser listar um RecordStore deve-se testar se
ainda existe aquele record, por comparao de Arrays, atravs do mtodo,
get?ecordSi;e().
Os records podem ser "listados" a partir de RecordEnumeration. Na Classe
Recorstore temos um mtodo que lista todos os records de determinada recordStore,
retornando um ?ecord$numeration. Este mtodo o:
?ecordStore.enumerate?ecords();
sso serve para que seja possvel percorrer todos os elementos do recordStore a
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
20
partir dos metodos da classe RecordEnumeration, nextRecord(), previousRecord().
Para controlar o lao de listagem desses records, usa-se o metodo
has0e%t$lement() do ?ecord$numeration.
mportante saber que quando um record excludo, os ndices(Ds) dos
elementos permanecem como esto, no h reorganizao dos Ds. Apenas possvel
reorganizar o Enumeration desse RecordStore.
Este mtodo pede parmetros de comparao que no abordaremos agora,
porm o mtodo pode ser usado como descrito abaixo:
rec$num=rs$%cluir.enumerate?ecords(null!null!3alse);
Ou seja, retorna todos os elementos e o "false" informa que esse Enumeration
no ser reorganizado automaticamente, caso haja alguma alterao na RecordStore.
Para eliminar um Enumeration usa-se o mtodo destroy().
- Canvas
Como j vimos, Canvas uma classe extendida de Displayable, que nos permite
trabalhar livremente com grficos e figuras em mais baixo nvel.
A partir da classe Graphics que podemos desenhar figuras primitivas, imagens
e textos em qualquer lugar dentro do espao de resoluo da tela do dispositivo.
Tambm a partir do Canvas que podemos desenvolver animaes como jogos
e apresentaes, usando-se recursos de Threads (processamento concorrente), porm
no trataremos disso nesse artigo.
- Codi,iando
A estrutura bsica de uma MDlet d-se por:
/*********** inicio do cdigo **********************/
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class HelloWorld extends MIDlet implements CommandListener
{
public HelloWorld ( { } 22metodo construtor da classe;
public void start!pp( { } 22mDtodo chamado sempre ao inEcio de
uma aplicaF:o
public void pause!pp( { } 22mDtodo chamado Guando a aplicaF:o D
interrompida! por e%emplo! Guando chega uma ligaF:o! ou uma
mensagem sms.
public void destro"!pp(boolean condicional { } 22mDtodo chamado
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
21
Guando uma aplicaF:o serH 3echada! ela 3ica aguardando o 7arbage
Collector
public void command!ction(Command c# Displa"able d
{
22mDtodo onde serH implementado Guase toda aplicaF:o! e os
comandos chamados pelas so3tCeys
}
}
/******************** Fim do Cdigo ************************/
Com isso podemos ver que a estrutura de uma aplicao simples, porm, por
ser assim to simples s vezes restringe a implementao.
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
22
Cdigos Exemplos
Obs: Comentrios j feitos no sero repetidos;
$xemploCommands!nd%ic&er
import =ava%.microedition.midlet.I;
import =ava%.microedition.lcdui.I;
public class $%emploCommandsAnd"ic4er e%tends J+Dlet implements
Commandistener
{
Display tela;
"e%t-o% te%to;
"ic4er tic4er;
Command sair! opcao.! opcaoK! opcao6! opcaoL! opcao<;
public $%emploCommandsAnd"ic4er()
{
22 instanciar "e%t-o%
this.te%to = ne' "e%t-o%(MCommandsM! MAplicaF:o iniciadaM! K,!
"e%t/ield.A01);
this.tic4er = ne' "ic4er(M$%emplo de tic4er Gue deve rodar em cima da
telaM);
22seta o tic4er na tela
this.te%to.set"ic4er(this.tic4er);
22 comandos do "e%t-o%
this.sair = ne' Command(MSairM! Command.$*+"! ,);
this.opcao. = ne' Command(MBpF:o .M! Command.SC?$$0! .);
this.opcaoK = ne' Command(MBpF:o KM! Command.SC?$$0! K);
this.opcao6 = ne' Command(MBpF:o 6M! Command.SC?$$0! 6);
this.opcaoL = ne' Command(MBpF:o LM! Command.SC?$$0! L);
this.opcao< = ne' Command(MBpF:o <M! Command.SC?$$0! <);
22 relacionar Commands com "e%t-o%
this.te%to.addCommand(sair);
this.te%to.addCommand(opcao.);
this.te%to.addCommand(opcaoK);
this.te%to.addCommand(opcao6);
this.te%to.addCommand(opcaoL);
this.te%to.addCommand(opcao<);
22 registrar "e%t-o% com o Commandistener
this.te%to.setCommandistener(this);
}
public void startApp()
{
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
23
22 obter tela do dispositivo
this.tela = Display.getDisplay(this);
22 setar Displayable corrente para a tela
this.tela.setCurrent(this.te%to);
}
public void pauseApp()
{
}
public void destroyApp(boolean i)
{
}
22aGui precisamos de um command e um displayable
22o displyable serH o componinte ativo na tela
22porGue ele e%tende de Display
public void commandAction(Command c! Displayable d)
{
i3 (c == this.sair)
{
22 sair da aplicaF:o
this.destroyApp(true);
this.noti3yDestroyed();
}
i3 (c == this.opcao.)
{
22 alterar te%to do "e%t-o%
this.te%to.setString(MBpF:o . selecionada.M);
this.tic4er.setString(MBpF:o . SelecionadaM);
}
22...
22pode>se implementar as outras opcoes aGui
22use a imaginacao
22ou espere aprender mais algumas coisas e entao acrescente
}
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
24
$xemploList!nd!lert
import =ava%.microedition.lcdui.I;
import =ava%.microedition.midlet.I;
public class $%emploistAndAlert e%tends J+Dlet implements
Commandistener
{
Display tela;
"e%t-o% t.;
Command sair! pro%! pro%.;
Alert alarme! con3irmacao! erro! in3o! aviso;
ist menu! e%clusiva! multipla;
public $%emploistAndAlert()
{
22criamos os arrays de opcoes Gue irao aparecer nas lists
String89 menu$lementos = { MAlarmeM! MCon3irmaF:oM! M$rroM! M+n3oM!
MAvisoM! M$%clusivaM! MJultiplaM };
String89 e%clusiva$lementos = { MBpcao.M! MBpcaoKM! MBpcao6M! MBpcaoLM!
MBpcao<M! MBpcaoNM };
String89 multipla$lementos = { MBpcao.M! MBpcaoKM! MBpcao6M! MBpcaoLM!
MBpcao<M! MBpcaoNM };
22instancia todos os alerts
22vamos dei%ar todos eles com null no campo de icone
this.alarme = ne' Alert(MAlarmeM!MAlerta de
AlarmeM!null!Alert"ype.AA?J);
22setamos o tempo Gue ele 3icarH na tela antes de sumir
this.alarme.set"imeout(<,,,);
this.con3irmacao = ne' Alert(MCon3irmacaoM!MAlerta de
con3irmacaoM!null!Alert"ype.CB0/+?JA"+B0);
this.con3irmacao.set"imeout(L,,,);
this.erro = ne' Alert(M$rroM!MAlerta de $rroM!null!Alert"ype.$??B?);
223i;emos deste alert! um alert modal
22Gue esperarH uma intervencao do usuario
this.erro.set"imeout(Alert./B?$O$?);
this.in3o = ne' Alert(M+n3oM!MAlerta de +n3oM!null!Alert"ype.+0/B);
this.aviso = ne' Alert(MAvisoM!MAlerta de AvisoM!null!Alert"ype.PA?0+07);
22instancia os comandos
this.pro% = ne' Command(M#ro%M!Command.SC?$$0!.);
this.pro%. = ne' Command(M#ro%M! Command.SC?$$0!.);
this.sair = ne' Command(MSairM!Command.$*+"!,);
22instancia os te%tbo%
this.t. = ne' "e%t-o%(M?esultM!MM!K,,!"e%t/ield.A01);
22relacionar comandos as te%tbo%es
this.t..addCommand(sair);
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
25
this.t..setCommandistener(this);
22instanciar lists
22criando a lista e%clusiva com o array de elementos criado acima
this.e%clusiva = ne' ist(M$%clusivaM! Choice.$*CQS+O$!
e%clusiva$lementos! null);
this.e%clusiva.addCommand(this.sair);
this.e%clusiva.addCommand(this.pro%);
22criando a lista multipla com o array de elementos criado acima
this.multipla = ne' ist(MJultiplaM! Choice.JQ"+#$!
multipla$lementos! null);
this.multipla.addCommand(this.sair);
this.multipla.addCommand(this.pro%.);
22criando a lista implicita com o array de elementos criado acima
22esta lista sera noss menu principal
this.menu = ne' ist(MJenuM!Choice.+J#+C+"!menu$lementos!null);
this.menu.addCommand(this.sair);
this.menu.setCommandistener(this);
}
public void startApp()
{
this.tela = Display.getDisplay(this);
this.tela.setCurrent(this.menu);
}
public void destroyApp(boolean i)
{
}
public void pauseApp()
{
}
public void commandAction(Command c! Displayable d)
{
String opcao = MM;
i3 (c == this.sair)
{
this.destroyApp(true);
this.noti3yDestroyed();
}
i3 (c == this.pro%)
{
22pega a String do item selecionado para por no te%tbo%
opcao = this.e%clusiva.getString
(this.e%clusiva.getSelected+nde%());
this.t..setString(opcao);
this.tela.setCurrent(this.t.);
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
26
i3 (c == this.pro%.)
{
22usamos esse laFo para veri3icar Guais opFRes
223oram selecionadas para entao apresentalas
3or(int count=,; countSN; countTT)
{
i3 (this.multipla.isSelected(count))
{
22adicionamos as opcoes em uma string sU
opcao = opcaoTthis.multipla.getString(count)TMVnM;
}
}
this.t..setString(opcao);
this.tela.setCurrent(this.t.);
}
22aGui comparamos se o comando veio de uma lista
22e tambem se a lista era a lista menu
i3 ((c == ist.S$$C"ACBJJA0D) WW (d == this.menu))
{
int selecionado = this.menu.getSelected+nde%();
22aGui veri3icamos se 3oi selecionado um dos Alerts
22entao ele eh acionado! e apos ser mostrado
22a tela anterior Gue D o menu
22eh mostrado novamente
s'itch (selecionado) {
case ,&
this.tela.setCurrent(this.alarme);
brea4;
case .&
this.tela.setCurrent(this.con3irmacao);
brea4;
case K&
this.tela.setCurrent(this.erro);
brea4;
case 6&
this.tela.setCurrent(this.in3o);
brea4;
case L&
this.tela.setCurrent(this.aviso);
brea4;
22aGui temos as outras listas...
case <&
this.e%clusiva.setCommandistener(this);
this.tela.setCurrent(this.e%clusiva);
brea4;
case N&
this.multipla.setCommandistener(this);
this.tela.setCurrent(this.multipla);
brea4;
}
}
}
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
27
$xemplo%ext'ox
import =ava%.microedition.lcdui.I;
import =ava%.microedition.midlet.I;
public class $%emplo"e%t-o% e%tends J+Dlet implements Commandistener
{
"e%t-o% nome! mail! resultado! senha;
Command sair! pro%imo! login! 3im;
Display tela;
public $%emplo"e%t-o%()
{
--,on(t&4to&e( do( *t&i64to( de'indo( *,im*
this.nome = ne' "e%t-o%(M0omeM!MM! K,! "e%t/ield.A01);
this.senha = ne' "e%t-o%(MSenhaM!MM! K,! "e%t/ield.#ASSPB?D);
this.mail = ne' "e%t-o%(MJailM! MM! K,! "e%t/ield.$JA+ADD?);
this.resultado = ne' "e%t-o%(M?esultadoM! MM! 6,! "e%t/ield.A01);
--,on(t&4to&e( do( ,omm*nd( 74e i&*o (e& *di,ion*do( *o( o68eto(
this.sair = ne' Command(MSairM! Command.$*+"! ,);
this.pro%imo = ne' Command(M#ro%imoM! Command.SC?$$0! .);
this.login = ne' Command(MoginM! Command.SC?$$0! .);
this.3im = ne' Command(M/imM! Command.SC?$$0! .);
--*di,*o do( ,omm*nd( *o( *o( o68eto(, e (9o (et*do( ,omo
,omm*nd/i(tene&
this.nome.addCommand(this.sair);
this.nome.addCommand(this.pro%imo);
this.nome.setCommandistener(this);
this.senha.addCommand(this.sair);
this.senha.addCommand(this.login);
this.senha.setCommandistener(this);
this.mail.addCommand(this.sair);
this.mail.addCommand(this.3im);
this.mail.setCommandistener(this);
this.resultado.addCommand(this.sair);
this.resultado.setCommandistener(this);
}
--m:todo exe,4t*do *o ini,io de 2xe,4;*o d* <)%let
public void startApp()
{
this.tela = Display.getDisplay(this);
this.tela.setCurrent(this.nome);
}
--m:todo exe,4t*do (e * <)%let 'oi& .*4(*d* .o& el* me(m*
--o4 .o& 4m e5ento exte&no
public void pauseApp()
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
28
{
}
--m:todo ,=*m*do 74*ndo * *.li,*;9o 'o& en,e&&*d*,
--n9o => ne,e((id*de de (e& im.lement*d*
public void destroyApp(boolean condicional)
{
}
--m:todo ,=*m*do *((im 74e 4m ,omm*nd 'o& *di,ion*do.
public void commandAction(Command c! Displayable d)
{
--de'ini;*o do 74e (e&> 'eito 74*ndo 4m ,omm*nd 'o& *,ion*do
i3 (c == this.sair)
{
this.noti3yDestroyed(); --noti'i,* 74e (e&> de(t&4ido
this.destroyApp(true); --,=*m* o de(t&4to&
}
i3 (c == this.pro%imo)
{
this.tela.setCurrent(this.senha); --(et* ,omo *ti5o n* tel*
}
i3 (c == this.login)
{
this.tela.setCurrent(this.mail);
}
i3 (c == this.3im)
{
--(et* * !t&in+ do o68eto &e(4lt*do .e+*ndo o 74e 'oi in(e&ido
--no( ,*m.o( *nte&io&e(.
this.resultado.setString(this.nome.getString()TM
MTthis.mail.getString());
this.tela.setCurrent(this.resultado);
}
}
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
29
$xemplo(orm)
import =ava%.microedition.lcdui.I;
import =ava%.microedition.midlet.I;
public class $%emplo/orm. e%tends J+Dlet implements Commandistener
{
Display tela;
/orm login! resultado;
"e%t/ield nome! senha;
String+tem resultadoJsg;
Command sair! pro%imo;
public $%emplo/orm.()
{
22 iniciali;ar Commands
this.sair = ne' Command(MSairM! Command.$*+"! ,);
this.pro%imo = ne' Command(M#ro%M! Command.SC?$$0! .);
22 3orm de login
this.login = ne' /orm(MoginM);
this.nome = ne' "e%t/ield(M0ome&M! MM! K,! "e%t/ield.A01);
this.senha = ne' "e%t/ield(MSenha&M! MM! K,! "e%t/ield.A01 X
"e%t/ield.#ASSPB?D);
22adiciona>se os componentes ao /orm ogin
this.login.append(this.nome);
this.login.append(this.senha);
this.login.addCommand(this.sair);
this.login.addCommand(this.pro%imo);
this.login.setCommandistener(this);
22 3orm de resultado
this.resultado = ne' /orm(M?esultadoM);
this.resultadoJsg = ne' String+tem(MM!MM);
22adiciona>se o componente ao /orm ?esultado
this.resultado.append(this.resultadoJsg);
this.resultado.addCommand(this.sair);
this.resultado.setCommandistener(this);
}
public void startApp()
{
this.tela = Display.getDisplay(this);
this.tela.setCurrent(this.login);
}
public void pauseApp()
{
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
30
public void destroyApp(boolean condicional)
{
}
public void commandAction(Command c! Displayable d)
{
i3 (c == this.sair) {
this.destroyApp(true);
this.noti3yDestroyed();
}
i3 (c == this.pro%imo) {
22B abel sempre aparecerH antes do "e%t n:o importando
22a ordem Gue vc adicione ele ao componente
223aFa o teste trocando de ordem as chamdas.
this.resultadoJsg.setabel(this.nome.getString()TM M);
this.resultadoJsg.set"e%t(this.senha.getString());
this.tela.setCurrent(this.resultado);
}
}
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
31
$xemplo*au+e
import =ava%.microedition.lcdui.I;
import =ava%.microedition.midlet.I;
22neste e%emplo vamos implementar mais duas inter3aces
22o +temStateistener vai nos a=udar a reconhecer as Setas direcionais
22do teclado do dispositivo.
22e a inter3ace ?unnable desempenha o papel de uma "hread
22onde poderiamos ter usado uma classe e%tra e%tendendo de "hread
22no entanto pre3erimos simpli3icar a implementaF:o.
22B processamente paralelo serH usado a3im de mostrar o
22movimento do gauge nao interativo.
22usamos o recurso de "hread por Gue n:o haveria possibilidade
22de incrementar nosso gauge! e mostra>lo na tela
22na mesma linha de e%ecuFao.
public class $%emplo7auge e%tends J+Dlet implements Commandistener!
+temStateistener! ?unnable
{
Display tela;
ist menu;
/orm gauge.! gaugeK;
7auge inter! ninter;
Command sairCommand! menuCommand;
"hread minha"hread;
public $%emplo7auge()
{
22 iniciali;ar Commands
this.sairCommand = ne' Command(MSairM! Command.$*+"! ,);
this.menuCommand = ne' Command(MJenuM! Command.SC?$$0! .);
22 menu principal
String89 menu$lementos = {M+nterativoM! M0:o +nterativoM};
this.menu = ne' ist(MJenu #rincipalM! ist.+J#+C+"!
menu$lementos! null);
this.menu.addCommand(this.sairCommand);
this.menu.setCommandistener(this);
22declararemos um 3or para cada gauge.
22 gauge interativo
this.gauge. = ne' /orm(M+nterativoM);
22setamos o label inicial do gauge
22true para torna>lo interativo
22<, D o numero de toGues Geu ele necessitarH para ser completado
22, para indicar seu inicio.
this.inter = ne' 7auge(M, YM! true! <,! ,);
this.gauge..append(this.inter);
this.gauge..addCommand(this.sairCommand);
this.gauge..addCommand(this.menuCommand);
this.gauge..setCommandistener(this);
22preparamos este 3orm para MouvirM os direcionais do teclado.
this.gauge..set+temStateistener(this);
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
32
22 gauge nao>interativo
this.gaugeK = ne' /orm(M0:o +nterativoM);
22mesma coisa Gue o gauge anterior!
22somente do 3alse indica Geu este gauge esta somente
22sobre controle do programa
this.ninter = ne' 7auge(M,YM! 3alse! .,,! ,);
this.gaugeK.append(this.ninter);
this.gaugeK.addCommand(this.sairCommand);
this.gaugeK.addCommand(this.menuCommand);
this.gaugeK.setCommandistener(this);
}
public void startApp()
{
this.tela = Display.getDisplay(this);
this.tela.setCurrent(this.menu);
}
public void pauseApp()
{
}
public void destroyApp(boolean condicional)
{
}
public void commandAction(Command c! Displayable d)
{
i3 (c == this.sairCommand)
{
this.destroyApp(true);
this.noti3yDestroyed();
}
i3 (c == this.menuCommand)
{
this.tela.setCurrent(this.menu);
}
22veri3ica Gual item da lista do menu principal 3oi selecionado
i3 (c == ist.S$$C"ACBJJA0D WW d == this.menu)
{
22se 3or o primeiro item Gue D o gauge interativo
22ele apresenta o gauge e espera por comandos.
i3 (this.menu.getSelected+nde%() == ,)
{
this.tela.setCurrent(this.gauge.);
}
22se 3or o gauge nao interativo! ele inicial nossa MthreadM
22a Gual controlarH nosso gauge 3a;endo>o aumentar atD onde determinarmos
i3 (this.menu.getSelected+nde%() == .)
{
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
33
this.tela.setCurrent(this.gaugeK);
this.minha"hread = ne' "hread(this);
minha"hread.start();
}
}
}
22controle do gauge interativo con3orme o valor vai mudando ele
22vai aprensentando na tela o valor correspondente
22e como setamos ele para Gue 3osse somente ateh <,
22multiplicamos por K os valores para supostamente
22chegar a .,,Y
public void itemStateChanged(+tem i)
{
i3 (i == this.inter)
{
this.inter.setabel(M MT(this.inter.getOalue()IK)TMYM);
}
}
22controle do gauge 0ao interativo
22e%ecuF:o da nossa "hread (?unnable)
public void run()
{
3or (int cont = .; cont S= .,,; contTT)
{
22 usamos este try>catch porGue precisamos usar o sleep
22para dar uma pausa peGuena para melhor vi;uali;acao
22do incremento.
22por curiosidade! auemnte e dimunua o valor do sleep
22lembre>se o valor D dado em milisegundos.
try
{
"hread.sleep(6,);
} catch ($%ception e)
{
}
this.ninter.setOalue(cont);
this.ninter.setabel(M MTcontTMYM);
}
}
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
34
$xemploConnectionIma+e
import =ava%.microedition.lcdui.I;
import =ava%.microedition.midlet.I;
import =ava%.microedition.io.I;
import =ava.io.I;
public class Connection+mage e%tends J+Dlet implements Commandistener
{
Display tela;
223orm onde serH e%ibida a imagem
/orm image/orm;

22+mage+tem onde a 3oto Gue virH do servidor serH salva.
+mage+tem 3oto;

22comandos
Command buscarCommand! sairCommand;

22string com a url para a imagem
22colocamos a url diretamente aGui somente para e%emplo
22uma idDia seria vc dei%ar o usuario setar esse lin4
22em um te%tbo% ou algo do genero.
String url = Mhttp&22'''.seusite.com.br2sua3oto.pngM;

public Connection+mage()
{
this.image/orm = ne' /orm(MM);
22image+tem onde serH posta a imagem Gue vier do server
22iniciali;amos ela com ;ero.
22o Gual poderia ser 3eito na hora de postar.
this.3oto = ne' +mage+tem(M3otoM!null!,!MM);
this.sairCommand = ne' Command(MSairM! Command.$*+"! ,);
this.buscarCommand = ne' Command(M-uscarM! Command.SC?$$0! .);
this.image/orm.addCommand(this.sairCommand);
this.image/orm.addCommand(this.buscarCommand);
this.image/orm.setCommandistener(this);
}
public void startApp()
{
this.tela = Display.getDisplay(this);
this.tela.setCurrent(this.image/orm);
}
public void pauseApp()
{
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
35
public void destroyApp(boolean bool)
{
}
public void commandAction(Command c! Displayable d)
{
i3 (c == this.sairCommand)
{
this.destroyApp(true);
this.noti3yDestroyed();
}
else i3(c == buscarCommand)
{
22se =H houver um +mage+tem no 3orm
22ele irH deleta>lo antes de =ogar uma nova imagem
i3 (image/orm.si;e() Z ,){
3or (int i = ,; i S image/orm.si;e(); iTT)
image/orm.delete(i);
}
try
{
+mage im;
22chama o mDtodo Gue busca a imagem
im = get+mage(this.url);
this.3oto.set+mage(im);
image/orm.append(this.3oto);
22 Display the 3orm 'ith the image
this.tela.setCurrent(image/orm);
}catch($%ception e)
{
}
}
}
2I>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
I Abre uma cone%:o http e bai%a um arGuivo png
I em um array de bytes
I>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>I2
private +mage get+mage(String url) thro's +B$%ception
{
22usamos aGui ao invDs de httpconnection
22a cone%ao padrao! o Gual nao nos garante nada.
22embora a cone%ao http tambem nao se=a muito con3iavel.
ContentConnection connection = (ContentConnection) Connector.open(url);
Data+nputStream iStrm = connection.openData+nputStream();
+mage im = null;
try
{
byte imageData89;
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
36
int length = (int) connection.getength();
i3 (length [= >.)
{
imageData = ne' byte8length9;
22 e um png em um array
iStrm.read/ully(imageData);
}
else 22se o tamanho n:o estH disponEvel
{
-yteArrayButputStream bStrm = ne' -yteArrayButputStream();
int ch;
'hile ((ch = iStrm.read()) [= >.)
bStrm.'rite(ch);
imageData = bStrm.to-yteArray();
bStrm.close();
}
22Cria a imagem de um array de bytes
im = +mage.create+mage(imageData! ,! imageData.length);
}
3inally
{
22 Clean up
i3 (iStrm [= null)
iStrm.close();
i3 (connection [= null)
connection.close();
}
return (im == null \ null & im);
}
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
37
$xemploHttpConnection
-?2(te exem.lo '*@ 4m* ,onex*o =tt. ,om 4m (e&5e&, o 74*l &eto&n*
4m li(t* de 4(4*&io( do( 74*i( no( .odemo( ent*o '*@e& 4m*
,on(4lt* *.en*( (ele,ion*ndo ele d* li(t* e * o4t&* 4&l no(
&eto&n*&> o( d*do(, d* .e((o*.
)(to : (A 4m exem.lo, * .*&te !e&5e&!ide 'i,* de (4*
&e(.on(*6ilid*de, 5i(to 74e n*o : e(te no((o o68eti5o.
A( .*+in*( .odem t*nto (e& .8(., ,omo !e&5let(.
?-
import =ava%.microedition.lcdui.I;
import =ava%.microedition.midlet.I;
import =ava%.microedition.io.I;
import =ava.io.I;
public class $%emploConnect e%tends J+Dlet implements Commandistener
{
Display tela;
ist registros! result;
Command sair! listar! voltar;
String url = M'''.seusite.com.br2sua#agina.=spM;
public $%emploConnect()
{
this.sair = ne' Command(MSairM!Command.$*+"! ,);
this.listar = ne' Command(MistarM!Command.SC?$$0! .);
this.voltar = ne' Command(MOoltarM! Command.SC?$$0! ,);
this.registros = ne' ist(MClientesM!ist.+J#+C+");
this.registros.addCommand(this.sair);
this.registros.addCommand(this.listar);
this.registros.setCommandistener(this);
this.result = ne' ist(MDados ClienteM! ist.+J#+C+");
this.result.addCommand(this.voltar);
this.result.setCommandistener(this);
}
public void startApp()
{
this.tela = Display.getDisplay(this);
this.tela.setCurrent(this.registros);
}
public void pauseApp()
{
}
public void destroyApp(boolean b)
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
38
{
}
public void commandAction(Command c! Displayable d)
{
i3(c == this.sair)
{
this.destroyApp(true);
this.noti3yDestroyed();
}
22chama a 3unF:o Gue 3a; a cone%ao com a pagina.
i3(c == this.listar)
{
this.conecta(this.registros);
}
22Guando chamar o voltar limpa a lista para evitar
22Gue se=am readicionados os mesmo itens na pro%ima cone%ao
i3(c == this.voltar)
{
int tamanho = this.result.si;e();
3or(int i= ,; i S tamanho; iTT)
{
this.result.delete(i);
}
this.tela.setCurrent(this.registros);
}
22veri3ica o item escolhido e entao pega o codigo
22e o =unta com a url para 3a;er a busca no servidor
i3(c == ist.S$$C"ACBJJA0D)
{
String linha = this.registros.getString
(this.registros.getSelected+nde%());
String cod = linha.substring(,!linha.inde%B3(M>M));
String url-usca = M'''.seusite.com.br2-uscaCodigo.=sp\cod=M;
this.url = url-uscaTcod;
22passamos a lista como parametro
22pois D onde sera montado o resultado da busca
this.conecta(result);
this.tela.setCurrent(this.result);
}
}
public void conecta(ist lista)
{
try
{
22estabelecemos uma cone%ao http com a url.
@ttpConnection con = (@ttpConnection) Connector.open(this.url);
int status = >.;
status = con.get?esponseCode();
22como a cone%ao 3oi http! D veri3icado o status da cone%ao
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
39
i3(status == @ttpConnection.@""#ABC)
{
+nputStream is = con.open+nputStream();
String-u33er sb = ne' String-u33er();
int lido = is.read();
22como podemos perceber abai%o
22D lido byte a byte do servidor.
'hile (lido [= >.)
{
byte b. = (byte)lido;
i3(b. == (byte)]Vn])
{
lista.append(sb.toString()!null);
sb.setength(,);
}
else
{
sb.append((char)b.);
}
lido = is.read();
}
}
22se nao conseguir estabelecer cone%ao!
22colocamos esta mensagem como padrao.
else
{
lista.append(M0enhum ?egistro $ncontrado[M! null);
}
}
catch (+B$%ception io.)
{
}
}
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
40
$xemploCanvas
-?
B*mo( ,on(t&4i& 4m exem.lo do 4(o do C*n5*( em D2<2.
C*n5*( : o 4(o de +&*'i,o( em ni5el 6*ixo.
B*mo( * ele...
?-
import =ava%.microedition.lcdui.I;
import =ava%.microedition.midlet.I;
-- Tod* * *.li,*,*o tem 74e Eextende&E de <)%let, e im.lement*& .elo
meno( *
-- inte&'*,e Comm*nd/i(tene&, ,*(o 5, 74ei&* te& inte&*+i& ,om *
*.li,*;9oF
public class $%emploCanvas e%tends J+Dlet implements Commandistener
{
Display tela;
Command sair;
-- .*&* de(en=*& n* tel* .&e,i(*mo( d* Cl*((e C*n5*(
-- ,omo no((* ,l*((e .&in,i.*l n9o .ode extende& * ,l*((e C*n5*(
-- ,&i*&emo( 4m* o4t&* Cl*((e 74e extend* de C*n5*(
0ossaCanvas canvas; 22classe criada mais a bai%o
public $%emploCanvas()
{
this.tela=Display.getDisplay(this);
this.sair=ne' Command(MSairM!Command.$*+"!,);
-- ini,i* o No((oC*n5*(
this.canvas=ne' 0ossaCanvas();
--*di,ion* o ,om*ndo (*i& *o ,*n5*(
this.canvas.addCommand(this.sair);
-- .&e.*&* o ,*n5*( .*&* Ee(,4t*&E o( ,om*ndo(
this.canvas.setCommandistener(this);
}
public void startApp()
{
--de'ine * tel* .*&* o o68eto No((oC*n5*( 74e 5*i de(en=*&
n* tel*
this.tela.setCurrent(this.canvas);
}
public void pauseApp()
{
-- n9o .&e,i(* exe,4t*& n*d* (e n9o 74i(e&
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
41
public void destroyApp(boolean b)
{
-- n9o .&e,i(* exe,4t*& n*d* (e n9o 74i(e&
}
-- metodo *6(t&*to d* inte&'*,e Comm*nd/i(tene&, : *ti5*do 74*ndo
*l+4m ,om*ndo : *,ion*do
public void commandAction(Command c! Displayable d)
{
-- &e,on=e,e 74e o ,om*ndo 'oi o (*i& e exe,4t*.
i3(c==this.sair)
{
this.destroyApp(true);
this.noti3yDestroyed();
}
}
}
--,l*((e ,&i*d* extendendo de C*n5*(
class 0ossaCanvas e%tends Canvas
{
public 0ossaCanvas()
{
}
-- metodo *6(t&*to de C*n5*( 74e .int* n* tel*
--ele : *,ion*do n* ,&i*,*o do o68eto e 74*ndo 4(*G(e o metodo &e.*int()
public void paint(7raphics g)
{
g.setColor(K<<!K<<!K<<); --de'ine 4m* ,o& $3B
g.3ill?ect(,!,!^N!NL); --,&i* 4m &et*n+4lo 8* .int*do ,om * ,o& de'inid*
g.setColor(.K_); --exi(te t*m6:m 4m* (o6&e,*&+* .*&* e(te m:todo ,om ,o&
de H 6it(
g.dra'?ect(<!<!__!<^); --de(en=* 4m &et*n+4lo (em .&een,=imento
g.setColor(.^K);
--,&i*G(e 4m* 5*&i*5el !t&in+ .o&74e o m:todo d&*w!t&in+() n*o *,eit* o
4(o de l*l* di&et*mente no m:todo.
String teste=M0oSSo CanvasM;
-- de'ine o texto *( ,oo&den*d*(, e onde *( ,oo&den*d*( de5em (e&
,on(ide&*d*( n* (t&in+
g.dra'String(teste!`!`!7raphics.$/"X7raphics."B#);
}
}
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
42
<e,er>nias 5i3liogr?,ias
@eogh0 Ja1es - J2ME The Complete Reference Editora Osborne
@nudsen0 Jonathan Wireless Java Developing with J2ME Editora Apress
Al1eida0 8eandro 5atista de - Material de Apoio
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003
43
Copyright
No autorizado o uso desta apostila indevidamente sem autorizao, entenda-
se reproduo para fins lucrativos.
Tutorial J2ME - Juliano Carniel e Clvis Teixeira
Copyright - 2003