Você está na página 1de 110

Java ME

Autor: Ricardo da Silva Ogliari

LISTAGEM 1: MIDLET BSICA EXEMPLIFICANDO CICLO DE VIDA. .............................................. 19 LIISTAGEM 2: CDIGO PARA MOSTRAR UM OBJETO FORM AO USURIO. .................................. 23 LISTAGEM 3: CLASSE QUE USA UM COMMAND DO TIPO EXIT....................................................... 28 LISTAGEM 4: CONSTRUTORES DA CLASSE ALERT............................................................................. 31 LISTAGEM 5: CDIGO NECESSRIO PARA GERAR UM TEXTBOX. .................................................. 33 LISTAGEM 6: CLASSE QUE MANIPULA O COMPONENTE TEXTBOX. .............................................. 35 LISTAGEM 7: CLASSE QUE MANIPULA O COMPONENTE LIST. ....................................................... 38 LISTAGEM 8: TRECHO DE CDIGO DA CLASSE EXFORM QUE IMPLEMENTA A ITEMSTATELISTENER. ................................................................................................................... 42 LISTAGEM 9: TRECHO DE CDIGO DA CLASSE EXSTRINGITEM QUE APRESENTA A FORMA DE UTILIZAO DO ITEM. .................................................................................................................. 48 LISTAGEM 10: TRECHO DE CDIGO DA CLASSE EXTEXTFIELD QUE APRESENTA A FORMA DE UTILIZAO DO TEXTFIELD........................................................................................................ 53 LISTAGEM 11: TRECHO DE CDIGO QUE APRESENTA A CRIAO DE CONFIGURAO DOS DOIS COMPONENTES DATEFIELD DATE_TIME. ...................................................................... 54 LISTAGEM 12: CLASSE DE EXEMPLO DE USO DO COMPONENTE DATEFIELD. .......................... 59 LISTAGEM 13: CLASSE DE EXEMPLO DE USO DO COMPONENTE DATEFIELD. .......................... 63 LISTAGEM 14: EXEMPLO DE USO DO GAUGE INTERATIVO. ........................................................... 65 LISTAGEM 15: EXEMPLO DE USO DO GAUGE COM THREAD. ........................................................ 66 LISTAGEM 16: EXEMPLO DE USO DA CLASSE SPACER. ................................................................... 68 LISTAGEM 17: MIDLET QUE FAZ USO DA CLASSE CUSTOMITEM .................................................. 70 LISTAGEM 18: CLASSE QUE HERDA DIRETAMENTE DE CUSTOMITEM. ....................................... 73 LISTAGEM 19: MTODO PAINT DA CLASSE QUE HERDA DIRETAMENTE DE CUSTOMITEM .... 73 LISTAGEM 20: USO PRIMRIO DA CLASSE CANVAS .......................................................................... 85 LISTAGEM 21: UTILIZAO DE RETNGULOS ................................................................................... 87 LISTAGEM 22: CONFIGURANDO FULL SCREEN MODE NO CANVAS. ............................................. 88 LISTAGEM 23: DESENHO DE LINHAS NO CANVAS ............................................................................. 90 LISTAGEM 24: DESENHO DE ARCOS NO CANVAS .............................................................................. 91 LISTAGEM 25: DESENHO DE LINHAS NO CANVAS ............................................................................. 92 LISTAGEM 26: DESENHO UMA IMAGEM NO CANVAS ....................................................................... 95 LISTAGEM 27: DESENHO UMA IMAGEM NO CANVAS ....................................................................... 97 LISTAGEM 28: MTODOS PARA CAPTURA DE EVENTOS DE PONTEIRO. .................................... 100 LISTAGEM 29: MTODO PARA ABRIR UM RECORD STORE. ........................................................... 104 LISTAGEM 30: MTODOS PARA FECHAR E DELETAR UM RECORD STORE. ............................... 104 LISTAGEM 31: MTODOS DE INSERO, ATUALIZAO E REMOO DE REGISTROS EM UM RECORD STORE. ........................................................................................................................... 105 LISTAGEM 32: MTODOS DE INSERO, ATUALIZAO E REMOO DE REGISTROS EM UM RECORD STORE. ........................................................................................................................... 106 LISTAGEM 33: ENUMERANDO REGISTROS DE UM RECORD STORE. ........................................... 106 LISTAGEM 34: ENUMERANDO REGISTROS DE UM RECORD STORE. ........................................... 107 LISTAGEM 35: ENUMERANDO REGISTROS DE UM RECORD STORE. ........................................... 107 LISTAGEM 36: ORDENANDO REGISTROS DE UM RECORD STORE. .............................................. 109

LISTAGEM 37: RECUPERANDO REGISTROS DE UM RECORD STORE. .......................................... 110

FIGURA 1: ARQUITETURA DA PLATAFORMA JAVA ME. -------------------------------------------------- 11 FIGURA 2: TELA PRINCIPAL DA IDE NETBEANS. ----------------------------------------------------------- 14 FIGURA 3: PRIMEIRO PASSO NA CRIAO DE UM NOVO PROJETO JAVA ME NO NETBEANS. 15 FIGURA 4: SEGUNDO PASSO NA CRIAO DE UM NOVO PROJETO JAVA ME NO NETBEANS. 16 FIGURA 5: TERCEIRO PASSO NA CRIAO DE UM NOVO PROJETO JAVA ME NO NETBEANS. 16 FIGURA 6: QUARTO E LTIMO PASSO NA CRIAO DE UM NOVO PROJETO JAVA ME NO NETBEANS. ---------------------------------------------------------------------------------------------------- 17 FIGURA 7: CICLO DE VIDA DE UMA APLICAO JAVA ME. -------------------------------------------- 19 FIGURA 8: RVORE DE CLASSES PARA INTERFACE GRFICA EM APLICAES JAVA ME. IMAGEM RETIRADA DE < HTTP://WWW.JAVAWORLD.COM/JAVAWORLD/JW-11-2003/JW1107-WIRELESS.HTML?PAGE=2>.----------------------------------------------------------------------- 25 FIGURA 9: COMMAND EXIT NO EMULADOR DE CELULAR AMPLAMENTE CONHECIDO. ------ 27 FIGURA 10: COMMAND EXIT EM UM DISPOSITIVO COM TECLADO QWERTY, PRESENTE EM ALGUNS SMARTPHONES E PDAS (PERSONAL DIGITAL ASSISTANT).--------------------------- 27 FIGURA 11: CLASSES PERTENCENTES QUE HERDAM DE SCREEN. IMAGEM RETIRADA DE < HTTP://WWW.DEVX.COM/WIRELESS/ARTICLE/21262/1954>. ------------------------------------- 29 FIGURA 12: ALERT SOMENTE COM TTULO. ---------------------------------------------------------------- 30 FIGURA 13: ALERT GERADO COM O CONSTRUTOR DE QUATRO PARMETROS. ----------------- 30 FIGURA 14: EXEMPLO DO COMPONENTE TEXTBOX. ----------------------------------------------------- 33 FIGURA 15: TELA RESULTANTE DA LISTAGEM 5. ---------------------------------------------------------- 36 FIGURA 16: LISTA INICIAL. -------------------------------------------------------------------------------------- 39 FIGURA 17: LISTA APS A EXECUO DO MTODO LSMAIN.DELETE(2). -------------------------- 39 FIGURA 18: LISTA APS A EXECUO DO MTODO LSMAIN.INSERT. ------------------------- 39 FIGURA 19: LISTA APS A EXECUO DO MTODO LSMAIN.SET(1, "PERA", NULL). ------------ 39 FIGURA 20: LISTA APS A EXECUO DO MTODO LSMAIN.APPEND("MAA", NULL). -------- 39 FIGURA 21: LISTA APS A EXECUO DO MTODO LSMAIN.SETFONT(). --------------------- 39 FIGURA 22: ITENS PRESENTES NA MIDP 2.0 QUE PODEM SER USADOS DENTRO DE UM OBJETO DA CLASSE FORM. RETIRADO DE: HTTP://WWW.DEVX.COM/WIRELESS/ARTICLE/21262/1954 ---------------------------------------- 43 FIGURA 23: CHOICEGROUP E SEUS TIPOS. ----------------------------------------------------------------- 44 FIGURA 24: CHOICEGROUP POPUP SELECIONADO. ----------------------------------------------------- 44 FIGURA 25: CHOICEGROUP POPUP SELECIONADO NO EMULADOR DO SGH-X800 DA SAMSUNG. ----------------------------------------------------------------------------------------------------- 45 FIGURA 26: EXEMPLOS DE STRINGITEM NO EMULADOR DO WTK DA SUN ------------------------ 47 FIGURA 27: EXEMPLOS DE STRINGITEM NO EMULADOR DO NOKIA 6165. ------------------------- 47 FIGURA 28: EXEMPLOS DE TEXTFIELD NO EMULADOR DO MOTOROLA RAZR ------------------- 50 FIGURA 29: EXEMPLOS DE TEXTFIELD NO EMULADOR DO WTK DA SUN ------------------------- 50 FIGURA 30: EXEMPLOS DE TEXTFIELD COM UM CAMPO TIPO PASSWORD ----------------------- 51 FIGURA 31: EXEMPLOS DE COMPONENTE DATEFIELD DATE E DATE_TIME. --------------------- 54 FIGURA 32: EXEMPLOS DE DATEFIELD NO EMULADOR DA SRIE 80 DA NOKIA. ---------------- 55 FIGURA 33: EXEMPLOS DE EDIO DE UM COMPONENTE DATEFIELD NO EMULADOR DA SRIE 80 DA NOKIA. ---------------------------------------------------------------------------------------- 56

FIGURA 34: EXEMPLOS DO COMPONENTE DATEFIELD NO EMULADOR DO APARELHO LG 160. ------------------------------------------------------------------------------------------------------------------- 56 FIGURA 35: EXEMPLO DE EDIO DO COMPONENTE DATEFIELD (MODO DATE) NO EMULADOR DO APARELHO LG 160. -------------------------------------------------------------------- 57 FIGURA 36: EXEMPLO DE EDIO DO COMPONENTE DATEFIELD (MODO DATE_TIME) NO EMULADOR DO APARELHO LG 160. -------------------------------------------------------------------- 57 FIGURA 36: EXEMPLO DE EDIO DA HORA DO COMPONENTE DATEFIELD NO EMULADOR DA SUN. -------------------------------------------------------------------------------------------------------- 58 FIGURA 37: EXEMPLO DE EDIO DA DATA DO COMPONENTE DATEFIELD NO EMULADOR DA SUN. -------------------------------------------------------------------------------------------------------- 58 FIGURA 37: EXEMPLO DE IMAGEITEM NO EMULADOR DA SRIE 80 DOS TELEFONES CELULARES DA NOKIA. ------------------------------------------------------------------------------------ 63 FIGURA 38: EXEMPLO DE INTERAO COM IMAGEITEM NO EMULADOR DA SRIE 80 DA NOKIA ---------------------------------------------------------------------------------------------------------- 63 FIGURA 39: EXEMPLO DE IMAGEITEM NO EMULADOR DO LG LX260. ------------------------------ 63 FIGURA 40: EXEMPLO DE INTERAO COM O IMAGEITEM NO EMULADOR DO LG LX260. --- 63 FIGURA 40: EXEMPLO DE GAUGE NO EMULADOR DA SUN. STRINGITEM SELECIONADO. ---- 67 FIGURA 41: EXEMPLO DE GAUGE NO EMULADOR DO APARELHO SANYO MM-5600. ----------- 67 FIGURA 42: EXEMPLO DE UTILIZAO DO GAUGE NO EMULADOR DO LG 325. ----------------- 68 FIGURA 43: CLASSE DE EXEMPLO DE GAUGE, COM A LINHA QUE ADICIONA O COMPONENTE AO FORM COMENTADA. ----------------------------------------------------------------------------------- 68 FIGURA 44: EXEMPLO DE CANVAS SEM FULLSCREEN. -------------------------------------------------- 76 FIGURA 45: EXEMPLO DE CANVAS SEM FULLSCREEN. -------------------------------------------------- 79 FIGURA 46: EXEMPLO DE CANVAS COM FULLSCREEN. ------------------------------------------------- 79 FIGURA 47: EXEMPLO DE CANVAS COM FULLSCREEN EXECUTANDO EM UM APARELHO SONY ERICSSON W380. ------------------------------------------------------------------------------------- 80 FIGURA 48: SISTEMA DE COORDENADAS DA GRAPHICS. ----------------------------------------------- 81 FIGURA 49: EXEMPLO DE ESTILOS DE LINHA NA CLASSE GRAPHICS. ------------------------------ 84 FIGURA 50: USO PRIMITIVO DA CANVAS. -------------------------------------------------------------------- 86 FIGURA 51: USO DE RETNGULOS NA CANVAS. ----------------------------------------------------------- 88 FIGURA 52: USO DE RETNGULOS NA CANVAS EM UMA TELA FULL SCREEN MODE. --------- 88 FIGURA 53: USO DE LINHAS NO CANVAS. ------------------------------------------------------------------- 90 FIGURA 54: USO DE ARCOS NO CANVAS. -------------------------------------------------------------------- 91 FIGURA 55: PONTO DE NCORA RIGHT USADO DE FORMA INADEQUADA. ----------------------- 93 FIGURA 56: PONTO DE NCORA LEFT USADO DE FORMA ADEQUADA. ---------------------------- 93 FIGURA 57: PONTO DE NCORA LEFT USADO DE FORMA ADEQUADA. ---------------------------- 94 FIGURA 58: DESENHO DE IMAGEM EM CANVAS. ---------------------------------------------------------- 95 FIGURA 59: EXEMPLO DE TECLADO NO FORMATO ITU-T. --------------------------------------------- 98 FIGURA 60: APARELHO CELULAR NOKIA N-95 8GB. ------------------------------------------------------ 99 FIGURA 61: RMS E SUA LIGAO COM MIDLETS. -------------------------------------------------------- 101 FIGURA 62: RECORD STORE. ----------------------------------------------------------------------------------- 102

1. Introduo ................................................................................................................7 2. A linguagem Java e suas plataformas ........................................................................9 3. Java ME Conceitos Iniciais....................................................................................11 4. Java ME Ambiente de produo ...........................................................................13 5. Ciclo de vida de uma MIDlet ....................................................................................18 6. Display e Displayable ................................................................................................21 7. Interface Grfica .......................................................................................................24 8. Command e CommandListener ...............................................................................26 9. Interface Grfica de Alto Nvel ................................................................................29 9.1 Alert ...................................................................................................................... 29 9.2 TextBox ................................................................................................................ 32 9.3 List ........................................................................................................................ 36 10. Interface Grfica de Alto Nvel Form .................................................................40 10.1 Itens .................................................................................................................... 42 10.2 ChoiceGroup ....................................................................................................... 43 10.3 StringItem ........................................................................................................... 46 10.4 TextField............................................................................................................. 49 10.5 DateField ............................................................................................................ 53 10.5 ImageItem ........................................................................................................... 59 10.6 Gauge .................................................................................................................. 63 10.7 Spacer ................................................................................................................. 67 10.8 CustomItem ........................................................................................................ 69 10.8.1 Modos de Interao ..................................................................................... 69 10.8.2 Traversal ...................................................................................................... 69 10.8.3 Aplicao Exemplo...................................................................................... 69 11. Interface grfica de baixo nvel - Canvas ..............................................................77 11.1 Canvas ................................................................................................................ 77 11.2 Modos de Operao ............................................................................................ 78 11.3 Graphics .............................................................................................................. 80 11.4 Estilo de Linha .................................................................................................... 84 12. Interface grfica de baixo nvel Programando ..................................................85 12.1 Desenhando retngulos ....................................................................................... 86 12.2 Desenhando linhas .............................................................................................. 89 12.3 Desenhando arcos ............................................................................................... 90 12.4 Ponto de ncora ................................................................................................. 92 12.5 Desenhando Textos ............................................................................................ 94 12.6 Desenhando Imagens .......................................................................................... 94 13. Interface grfica de baixo nvel - Interao com o usurio .................................97 13.1 Interao com eventos de teclado ....................................................................... 97 13.1 Interao com eventos de ponteiro ..................................................................... 99 14. Armazenamento de dados.....................................................................................101 14.1 Gerenciando os Record Stores do dispositivo ................................................. 103 14.2 Inserindo, atualizando e detelando registros .................................................... 104 14.3 Enumerando registros ....................................................................................... 106 14.3 Criando filtros na enumerao de registros ...................................................... 106 14.4 Ordendo os registros ......................................................................................... 108 14.5 Recuperando registros ...................................................................................... 109

1. Introduo
A computao mvel ganhou destaque nos ltimos anos, o conceito de mobilidade vem sendo empregado nos mais diversos ramos da sociedade, e, alm disso, das mais variadas formas possveis. O telefone celular um dos grandes responsveis por este acontecimento, hoje em dia, metade da populao mundial tem um aparelho, em alguns pases da Europa, o nmero destes dispositivos ultrapassou a quantidade de habitantes. O modo de vida das pessoas foi afetado drasticamente, a forma de conviver e existir na sociedade tambm sofrer alteraes profundas. A computao mvel vem sendo a grande menina dos olhos das grandes empresas, todo mundo quer oferecer seus servios em pequenos dispositivos, quer a fidelizao de seus clientes, levando sua marca at onde eles esto. Vrios termos ganharam vida com o advento da computao mvel, dentre os quais podemos citar: Mbile Payment e Mobile Commerce: a forma tradicional de compra e venda de mercadorias est se tornando obsoleta, depois do E-Commerce, a nova onda o Mobile Commerce, ou seja, o processo de aquisio de qualquer mercadoria pode ser feito diretamente pelo seu dispositivo mvel. O termo celular-carteira o exemplo mais claro desse termo. Mobile TV: a televiso analgica criada a algumas dcadas atrs tambm vai virar pea de museu, seu sinal est sendo convergido para digital, sendo assim, ele pode ser capturado por dispositivos mveis. Mobile Banking: a maioria das operaes bancrias comuns, como extrato, consulta de saldo e transferncia de valores entre contas bancrias, j possvel com dispositivos mveis. J possvel negociar papis em bolsa de valores em telefones celulares atravs do Mobile Broker. Mobile Learning: direciona o processo de aprendizado para pequenos dispositivos. Existem sistemas em 3D que simulam aos usurios a visita a museus, conhecendo as obras e sua histria.

Mobile Marketing: o marketing est enraizado na sociedade h vrios anos, agora, essa rea comea a mirar os dispositivos mveis. inegvel que estes aparelhos atingem um nmero muito grande de pessoas, ou seja, o foco do marketing. Alm das reas citadas anteriormente, a mobilidade atingiu vrias outras reas de conhecimento. Os dispositivos mveis, liderados pelos telefones celulares ultrapassaram faz tempo o nmero de computadores pessoais, e a tendncia, continuar o crescimento. A computao mvel faz parte de um conceito maior, chamado de computao ubqua. Este termo foi cunhado por Mark Weiser, pregando o uso da computao de forma inconsciente, fazendo com que a tecnologia se adapte aos seres humanos, e no o que acontece hoje. Para usarmos um notebook, por exemplo, sentamos na frente dele, se quisermos sair do cmodo onde estamos e ir at a cozinha, ou levamos o notebook junto ou vamos parar de trabalhar. A computao ubqua traria a computao para a cozinha de forma automtica, percebendo a mudana no ambiente e se adaptando a ela. Porque falei da computao ubqua? Isso porque ela no existe sem a computao mvel. Para haver ubiqidade deve necessariamente existir a mobilidade. O leitor deve estar ciente do surgimento dos automveis com Bluetooth, que podem ler mensagens SMS (Short Message Service) para o motorista, automveis que estacionam sozinhos, ou ainda, que adaptam os faris dependendo da direo que o carro est seguindo, e assim por diante. A indstria automobilstica um exemplo da fuso de tecnologias, e a computao mvel o grande motor disso, existe equipamento que apresenta maior convergncia de tecnologia como o telefone celular? Ficar indiferente a isso simplesmente suicdio, para empresas a falncia, para desenvolvedores um atraso na carreira. Hoje em dia a diversas opes, diferente do que acontecia a menos de uma dcada atrs. Hoje podemos usar Symbian C++, Brew, SuperWabba, Java ME e uma diversidade de tecnologias para a produo de aplicativos mveis. Cada uma delas tem seus pontos positivos e negativos, porm, indiscutivelmente, a plataforma Java ME da linguagem Java domina o mercado em relao aos telefones celulares no momento que este texto foi escrito. Sendo assim, o objetivo deste trabalho demonstrar a plataforma Java ME, com foco em programao para a configurao CLDC. Desde sua parte bsica at reas mais avanadas que julga-se indispensveis em um futuro prximo, como Bluetooth e mtodos de posicionamento geogrfico.

2. A linguagem Java e suas plataformas


A linguagem Java surgiu comercialmente em 1995 direcionada a qualquer produtor eletrnico, por isso a idia da mquina virtual e seus bytecodes. Porm, o boom da internet fez com que o Java tivesse sucesso inicial com os chamados Applets, aplicativos que permitiam que pginas web ganhassem dinamicidade. A linguagem cresceu rapidamente, com o passar dos anos seu uso foi se tornando extremamente segmentado, surgindo a idia de diviso da linguagem em plataformas. Com isso, a linguagem teve seu foco direcionado a reas distintas, obtendo sucesso diferenciado em cada uma delas. Atualmente, existem basicamente trs plataformas: Java Standart Edition: direcionada a computadores pessoais, foi a primeira a aparecer e tambm conta com o maior conjunto de APIs (Application Program Interface). Java Enterprise Edition: para ambientes servidores, um conjunto de componentes. Podemos citar alguns deles, como: JSP (Java Servlet Page), Servlets, Java Beans e Enterprise Java Beans. Java Micro Edition: a mais nova da famlia. Com o advento dos pequenos dispositivos, esta plataforma foi criada. Atende desde cartes inteligentes (smartcard) at Set Tob Box e PDAs ultra modernos. Porm, nos telefones celulares que seu uso mais difundido. Como o objetivo principal deste trabalho no ensinar a linguagem Java, mas a plataforma Java ME, no se tratado nenhum aspecto da linguagem aqui.

3. Java ME Conceitos Iniciais


A plataforma Java ME amplamente conhecida na programao para telefones celulares, porm, seu uso muito mais amplo e sua gama de aparelhos extensa. Assim como na histria da linguagem Java, a plataforma Java ME tambm sofreu algumas divises para se adaptar aos diferentes tipos de plataforma em que executada. Essa diviso chamada de configurao (Configuration). Ela define questes de baixo nvel, como a mquina virtual Java. As configuraes existentes so: CDC (Connected Device Configuration) e CLDC (Connected Limited Device Configuration). Os perfis (Profile) representam uma nova separao, levando em conta parmetros de alto nvel, como APIs para a interface de usurio por exemplo. Nesta categoria podemos citar: Foundation Profile, Personal Basis Profile e Personal Profile para CDC e MIDP (Mbile Information Device Profile) e IMP (Information Module Profile - Next Gen (IMP-NG)) para a CLDC. A arquitetura da Java ME pode ser encontrada na Figura 1.

Figura 1: Arquitetura da plataforma Java ME.

Na Figura 1, encontramos a arquitetura da plataforma Java ME, que encontrada acima do sistema operacional do dispositivo mvel. A configurao e o perfil foi dissertado no pargrafo anterior, porm, agora veremos onde se encaixam os pacotes opcionais. A idia do Java ME foi atingir os dispositivos limitados no que diz respeito a capacidade de processamento e armazenamento, porm, a tecnologia est evoluindo rapidamente, e a Java ME teve que se adaptar. Sendo assim, so criados periodicamente pacotes opcionais para serem usados junto com a configurao padro, direcionados aos aparelhos que suportam caractersticas especiais, como suporte a imagens SVG (Scalable Vector Graphics) e sua SVG API, ou ainda, suporte a dados georeferenciados, e a Java Location API. Alm disso, existem muitas outras funcionalidades que no so caractersticas bsicas de todos os dispositivos, como multimdia, internacionalizao, pagamento eletrnico, dentre outros, por isso existem os pacotes opcionais, impedindo que a Java ME fique presa aos equipamentos low-end e permitindo sua utilizao segmentada para os high-end. O Java ME pode ser direcionada a diversos tipos de equipamentos, porm, neste texto iremos focar o desenvolvimento para a configurao CLDC e seu perfil MIDP, muito usado em telefones celulares. Aplicativos desse porte so frequentemente chamados de MIDlets. Porm, os cdigos apresentados aqui que no apresentam interface grfica podem ser portados para o perfil IMP da CLDC, isso porque, este perfil se equivale ao MIDP, apenas no possui interface grfica com o usurio.

4. Java ME Ambiente de produo


Por ambiente de produo entendem-se as ferramentas necessrias para codificar, empacotar e distribuir uma aplicao Java ME. Por se tratar de uma plataforma da linguagem Java, as opes existentes hoje so extensas, diversas APIs fornecem at mesmo wizards para o desenvolvimento, porm, aqui veremos a parte de codificao, at mesmo para incentivar o entendimento do cdigo fonte de cada componente especfico. Ferramentas conhecidas como IDEs (Integrated development environment) fornecem ao desenvolvedor maneiras prticas e rpidas de codificar e empacotar uma aplicao. Neste trabalho ser utilizada a IDE NetBeans (http://www.netbeans.org/), ferramenta de cdigo aberto e grtis. Porm, se o leitor se sentir mais seguro utilizando outra IDE se sua preferncia sinta-se a vontade. Na produo deste contedo, o NetBeans est na verso 6.1 Release Candidate. Na pgina oficial da IDE possvel baixar uma verso prconfigurada especialmente para a plataforma Java ME. Se o leitor preferir uma verso mais antiga, talvez seja necessrio a instalao do Mobilite Pack, necessrio para o desenvolvimento em Java ME. A Figura 2 apresenta a tela principal do NetBeans.

Figura 2: Tela principal da IDE NetBeans.

O crculo vermelho indica a barra superior, com as opes comuns como salvar, abrir, fechar, configuraes, dentre outros. O crculo verde traz os componentes que podem ser inseridos em uma MIDlet. O crculo azul est sobre a listagem dos projetos anexados a IDE. A rea mais importante est marcada com o crculo preto, que representa a tela de codificao, onde todas as coisas acontecem de verdade. Para criar um projeto Java ME basta ir ao menu File ->New Project. Uma tela conforme a Figura 3 aparecer na tela. A opo Mobility marcada, na parte direita existem algumas opes, porm, para criao de uma MIDlet, a opo MIDP Application deve ser marcada. O prximo passo e clicar no boto Next.

Figura 3: Primeiro passo na criao de um novo projeto Java ME no NetBeans.

O segundo passo consiste em definir o nome e a localizao do projeto. O campo Project Name: define o nome do projeto. Em Project Location especifica-se a localizao onde o novo projeto ser armazenado, e, a sua pasta, definida no campo Project Folder. A caixa de seleo Set as Main Project define o novo projeto como o principal (se a caixa ficar marcada), isso significa, que o NetBeans ir executar as operaes de compilar e emular este projeto. Em Create Hello MIDlet define-se que o NetBeans criar automaticamente uma classe que ser uma MIDlet bsica. Neste texto no ser trabalhado esta parte, julga-se necessrio o conhecimento do cdigo como um todo, posteriormente, o leitor pode navegar por estas guas facilmente, isso porque, ter conhecimento amplo do Java ME.

Figura 4: Segundo passo na criao de um novo projeto Java ME no NetBeans.

Posteriormente (Figua 5), necessrio configurar a verso da CLDC e da MIDP que sero usadas no projeto. Alm do emulador e do dispositivo que ser usado. Perceba que a verso que est marcada o Sun Wireless Toolkit, da Sun Microsystem. Infelizmente essa ferramenta no condiz inteiramente com a realidade de alguns telefones celulares. Aconselha-se o uso de emuladores dos prprios fabricantes, possibilitando assim um exame mais apurado de como o aplicativo se comportar.

Figura 5: Terceiro passo na criao de um novo projeto Java ME no NetBeans.

O Device a ser escolhido referente ferramenta de emulao que est marca em Emulator Platform. A escolha da verso da CLDC e da MIDP de suma importncia no desenvolvimento de uma MIDlet, isso porque, a escolha pode restringir a abrangncia da soluo desenvolvida. A CLDC 1.0 no possui suporte nativo a nmeros em ponto flutuante, se for necessrio, deve ser usada uma API separada, como a MathFP por exemplo. Essa a principal diferena entre a CLDC 1.0 e a CLDC 1.1. A MIDP 2.0 traz vrias mudanas importantes em relao a sua precursora. O pacote GameCanvas permite a criao de jogos de uma maneira mais eficaz, contendo conceitos amplamente usadas na construo desse tipo de aplicativo. Alm disso, a MIDP 2.0 traz alguns componentes adicionais, como o javax.microedition.lcdui.CustomItem e javax.microedition.lcdui.Spacer. Alguns dos componentes ganharo novas funcionalidades, um deles, o Gauge pode ser includo em um Alert. Na classe javax.microedition.lcdui.Graphics foram adicionadas algumas diretivas grficas, como o desenho de tringulos. Sendo assim, a especificao da verso da MIDP e da CLDC de suma importncia para o projeto a ser desenvolvido. Felizmente, hoje em dia, o uso da MIDP 2.0 se sobressai substancialmente em relao a MIDP 1.0, se tornando um perfil padro, porm, vale lembrar que ainda existem aparelhos com a MIDP 1.0 e, dependendo do cliente ou do trabalho a ser desenvolvido, devem ser levados em conta. No momento da escrita desse trabalho a MIDP 3.0 ainda no havia sido lanada. A partir desse ponto o projeto j pode ser iniciado, ou, informaes adicionais sobre o projeto podem ser configuradas, dando um Next na tela anterior obteremos a ltima tela do wizard, ilustrada na Figura 6:

Figura 6: Quarto e ltimo passo na criao de um novo projeto Java ME no NetBeans.

5. Ciclo de vida de uma MIDlet


Uma MIDlet apresenta um ciclo de vida parecido com aquele adotado em Applets (aplicativos Java que executam em browser). Para facilitar o entendimento vamos imaginar um telefone celular. Na maioria dos modelos encontra-se uma pasta especfica para as aplicaes nativas do aparelho e outra para os aplicativos que o usurio instale depois da compra. Nesse local encontra-se uma lista das aplicaes instaladas no dispositivo. Quando escolhemos um item a MIDlet entra no estado Ativo. Quando algum evento externo acontecer, como uma mensagem SMS ou uma ligao, o AMS (Application Manager System, responsvel pelo gerenciamento de ativao e desativao das MIDlets presente no telefone celular) coloca a MIDlet em estado de espera, quando o evento externo se encerra, o MAS muda o status da MIDlet para ativo novamente. Finalmente, quando fechamos a aplicao o AMS coloca a aplicao no estado destrudo. A Figura 7 ilustra estes conceitos de forma grfica.

Figura 7: Ciclo de vida de uma aplicao Java ME.

J hora de vermos um pouco de cdigo no acham? Depois de dissertar sobre o ciclo de vida de uma MIDlet nada melhor que mostrar que cdigo que exemplifica tudo isso, veja a Listagem 1:
import javax.microedition.midlet.MIDlet; public class CicloVida extends MIDlet { public void startApp() { System.out.println("passa para o estado ativo"); } public void pauseApp() { System.out.println("passa para o estado de pausa"); } public void destroyApp(boolean unconditional) { System.out.println("passa para o estado desativado"); } }

Listagem 1: MIDlet bsica exemplificando Ciclo de Vida.

A primeira linha define o import necessrio para o uso da classe MIDlet. Um aplicativo desenvolvido em Java ME para pequenos dispositivos, s se comportar como tal, se o projeto possuir ao menos uma classe que herde

da classe MIDlet. Sendo assim o uso da palavra extends seguido da classe de suma importncia na construo do projeto. Quando existirem duas ou mais classes no projeto que herdem de MIDlet, todas ficaram dentro de uma MIDlet Sute. No instante que o usurio escolher o aplicativo no menu do seu aparelho, uma lista com todas as midlets presentes no Sute sero apresentadas. Para que o ciclo de vida seja construdo, a classe deve implementar obrigatoriamente trs mtodos: startApp(): chamado na inicializao do aplicativo, ou seja, quando o usurio escolhe o aplicativos na sua lista, o MAS chama o mtodo startApp() automaticamente: pauseApp(): usado para o correto gerenciamento de eventos externos. Quando uma ligao ou uma mensagem SMS chegam ao telefone celular por exemplo, o MAS chama automaticamente o pauseApp(), transferindo o estado da aplicao de ativo para pausado. destroyApp(): quando o usurio opta por fechar a aplicao, o MAS chama automaticamente o destroyApp(), liberando todos os recursos que eram usados por ela.

6. Display e Displayable
A classe java.mixroedition.lcdui.Display permite acesso ao display do dispositivo mvel. A classe oferece uma maneira de apresentar ao usurio os componentes presentes no pacote lcdui. Alm disso, oferece mtodos que capturam algumas caractersticas grficas, como a quantidade de cores, mtodos que permitem a vibrao do aparelho, dentre outros. A classe Displayable, presente no mesmo pacote, herdada por todos os componentes reutilizveis da MIDP, como DateFied, TextField, StringItem, dentro outros. Para criar uma instncia de Display necessrio o uso do mtodo esttico getDisplay(MIDlet midlet). Na tabela abaixo so listados os principais mtodos da classe Display e, em seguida da classe Displayable. Para maiores informaes recomenda-se a leitura da documentao da MIDP API.

Mtodos classe Display


boolean flashBacklight(int durao)

Requisita um efeito de flashing para o dispositivo. Este mtodo pode ser usado em jogos, informando o usurio de forma mais eficaz.
int getBestImageHeight(int tipoImagem)

Retorna a melhor altura para um determinado tipo de imagem.


int getBestImageWidth(int tipoImagem)

Retorna a melhor largura para um determinado tipo de imagem.


Displayable getCurrent()

Recupera a instncia do objeto Displayable que est sendo mostrado na MIDlet.


static Display getDisplay(MIDlet m) Retorna o objeto Display

que nico para a MIDlet recebida

por parmetro.
boolean isColor()

Retorna um valor booleano informando se o dispositivo suporta cores ou no.


int numAlphaLevels()

Retorna o nmero de nveis de transparncia suportados pela implementao da MIDP no dispositivo.


int numColors()

Recupera o nmero de cores (se o retorno do mtodo isColor() for true) ou nveis de tons de cinza (se o retorno do mtodo isColor() false) que podem ser representados pelo dispositivo.
void setCurrent(Alert alerta, Displayable proximoDisplayable) Requisita que a instncia de Alert seja mostrada no display, o proximoDisplayable seja mostrado depois que o Alert for

fechado.
void setCurrent(Displayable proximoDisplayable) Requisita que uma instncia de Displayable seja visualizada

no display do dispositivo..
void setCurrentItem(Item item) Requisita que o Displayable que contenha o Item seja mostrado, se o Item no estiver visvel o Displayable deve rolar

at o mesmo ficar em evidncia.


boolean vibrate(int duracao)

Requisita que o dispositivo vibre por um intervalo de tempo especificado por duracao.

Mtodos classe Displayable


void addCommand(Command comando)

Adiciona um command para o Displayable.


Ticker getTicker()

Recupera o ticker usado pelo Displayable.


String getTitle()

Retorna o ttulo do Displayable.


boolean isShown()

Checa se o Displayable est visvel no display.


void removeCommand(Command cmd)

Remove um command do Displayable.


void setCommandListener(CommandListener l)

Configura um listener para os Commands do Displayable, sobrescrevendo qualquer CommandListener previamente configurado.
void setTicker(Ticker ticker)

Configura um ticker para seu usado no Displayable..


void setTitle(String s)

Configura o ttulo do Displayable.

Com o decorrer dos exemplos, o entendimento das classes Display e Displayable ser completo. Apenas para comear, veja uma melhoria do

cdigo apresentado na Listagem 1. A Listagem 2 mostra oque necessrio fazer para mostrar para o usurio um objeto javax.microedition.lcdui.Form. Este componente ser explicado posteriormente, por hora, necessrio saber apenas que ele herda diretamente de Displayable.
import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Form; public class CicloVida2 extends MIDlet { private Display display; private Form fmMain; public void startApp() { display = Display.getDisplay(this); fmMain = new Form(Formulrio); display.setCurrent(fmMain); } public void pauseApp() { System.out.println("passa para o estado de pausa"); } public void destroyApp(boolean unconditional) { System.out.println("passa para o estado desativado"); } }

Liistagem 2: Cdigo para mostrar um objeto Form ao usurio.

7. Interface Grfica A construo de interfaces grficas em Java ME tem trs caminhos: o uso de componentes grficos prontos, a construo de telas personalizadas com diretivas grficas e, por fim, o uso de algum framework que personaliza alguns componentes padres da MIDP. O uso de componentes prontos, inseridos dentro do pacote javax.microedition.lcdui tornam o processo de desenvolvimento mais rpido, porm, no possvel adicionar cores, mudar fontes ou estilo de linhas dos componentes, eles so fechados. O uso de diretivas grficas torna o processo de codificao mais penoso, porm, o resultado grfico, na maioria das vezes, ser superior aos componentes, isso porque, o usurio pode fazer a combinao de diretivas que quiser, criando os mais variados tipos de interfaces. Alm disso, existem frameworks que podem ser entendidos como componentes mais amigveis, com opes de configurao de comportamento grfico. No decorrer do texto vamos demonstrar as duas primeiras formas, que so oriundas da API MIDP, os frameworks ficam como lio de casa para os leitores mais interessados. A Figura 8 ilustra uma breve arquitetura das classes do pacote javax.microedition.lcdui, responsvel pela interface grfica dos aplicativos Java ME.

Figura 8: rvore de classes para interface grfica em aplicaes Java ME. Imagem retirada de < http://www.javaworld.com/javaworld/jw-11-2003/jw-1107wireless.html?page=2>.

O ponto crucial a ser entendido na figura a diviso entre Screen (interface grfica de alto nvel) e Canvas (interface grfica de baixo nvel). Os dois no podem coexistir em uma instncia de um objeto Displayable, ou seja, ou usamos um ou outro para a interface. Optando por Screen tmse alguns componentes prontos para a utilizao. Com Canvas, tudo por parte da imaginao e codificao do programador.

8. Command e CommandListener Antes de comear a mexer nos componentes importante conhecer as classes javax.microedition.lcdui.Command e javax.microedition.lcdui.CommandListener. Os comandos so inseridos nas classes que herdam diretamente de Displayable, ou seja, Canvas, TexBox, Alert, List e Form, alm dos itens Gauge e Spacer. Eles so umas das formas mais primitivas de interao com o usurio. Excluindo as formas presentes no Canvas e nos componentes na MIDP, os comandos so a nica forma de contato com o usurio.

Construtor da classe Command


Command(String rotulo, int tipoComando, int prioridade)

Cria um novo objeto Command com um rtulo, tipo e prioridade.


Command(String rotuloCurto, String rotuloLongo, int tipoComando, int prioridade)

Cria um novo objeto Command com um rtulo curto e um longo, alm do seu tipo e prioridade.

Mtodos da classe Command


int getCommandType()

Retorna o tipo do comando.


String getLabel()

Retorna o rtulo curto do comando.


String getLongLabel()

Retorna o rtulo longo do comando.


int getPriority()

Retorna a prioridade do comando.

Um conceito importante a ser discutido aqui o tipo do comando. Este tipo uma das constantes da classe: BACK, CANCEL, EXIT, HELP, ITEM, OK, SCREEN, STOP. Por exemplo, se o tipo configurado for EXIT, ele no ter o comportamento de sair da aplicao, mas sim, ser

colocado onde o comando EXIT do aparelho est. A funcionalidade do comando quem configura o programador.

Figura 9: Command EXIT no emulador de celular amplamente conhecido.

Figura 10: Command EXIT em um dispositivo com teclado QWERTY, presente em alguns smartphones e PDAs (Personal Digital Assistant).

Perceba o comando Sair que est presente nas duas figuras acima, ambos tero o mesmo comportamento, que foi configurado pelo programador (ver Listagem 3), porm, esto em locais totalmente diferentes. Isso acontece porque a JVM do dispositivo define o local que o command do tipo EXIT ir ficar. A Listagem 3 mostra o cdigo necessrio para gerar o programa ilustrado nas figuras 9 e 10. A classe javax.microedition.lcdui.CommandListener o ouvidor que captura os eventos de seleo dos Commands. Para us-la, basta que a classe implemente a classe, atravs do uso da palavra reservada implements. Alm disso, o mtodo commandAction(Command c, Displayable d) deve ser implementado. O parmetro que especifica o

comando que originou o evento muito importante quando tempos vrias telas implementando o mesmo comando, sendo assim, podemos fazer um tratamento diferenciado dependendo da tela onde o comando foi acionado.
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class Commands extends MIDlet implements CommandListener{ private Form fmMain; private Display display; private Command cmSair; public void startApp() { display = Display.getDisplay(this); fmMain = new Form("Comandos"); cmSair = new Command("Sair", Command.EXIT, 1); fmMain.addCommand(cmSair); fmMain.setCommandListener(this); display.setCurrent(fmMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command c, Displayable d) { if (c == cmSair) { destroyApp(true); notifyDestroyed(); } } }

Listagem 3: Classe que usa um Command do tipo EXIT.

9. Interface Grfica de Alto Nvel O uso de componentes facilita o processo de codificao, isso indiscutvel, sendo assim, vamos comear por este mtodo, depois partiremos para a cereja do bolo. A classe Screen apresenta quatro classes que representam componentes grficos: Form, List, TextBox e Alert. A Figura 9 ilustra esta arquitetura. Vale ressaltar que no possvel mostrar duas instncias destas classes no mesmo Display.

Figura 11: Classes pertencentes que herdam de Screen. Imagem retirada de < http://www.devx.com/wireless/Article/21262/1954>.

9.1 Alert A classe javax.microedition.lcdui.Alert permite que o programador apresente um alerta para o usurio do aplicativo. Este alerta pode receber configuraes de som, de ttulo, de mensagem apresentada e da imagem que anexada. Nas duas tabelas abaixo encontra-se, respectivamente, os dois construtores da classe e os principais mtoodos.

Construtores da classe Alert


Alert(String ttulo)

Constri um novo objeto, um Alert vazio somente com o ttulo.


Alert(String titulo, String textoAlerta, Image imagemAlerta, AlertType tipoAlerta) Constri um novo objeto Alert com um ttulo, contedo, imagem e tipo

passados por parmetro.

O primeiro construtor resulta em um alerta semelhante ao da Figura 10, ou seja, somente com o ttulo. O segundo construtor insere, alm do ttulo, uma mensagem, uma imagem e um tipo, sendo que, um pequeno trecho de som vinculado ao Alert dependendo do tipo configurado, resultando na Figura 11.

Figura 12: Alert somente com ttulo.

Figura 13: Alert gerado com o construtor de quatro parmetros.

A Listagem 4 mostra o cdigo necessrio para a criao dos dois Alerts mostrados anteriormente.
import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Form; public class CicloVida2 extends MIDlet { private Display display; private Form fmMain; public void startApp() { display = Display.getDisplay(this); try { //alerta = new Alert("Mensagem"); //alerta somente com o ttulo //alerta completo alerta = new Alert("Mensagem", "Este um Alert completo", Image.createImage("/imagem.png"), AlertType.WARNING); } catch (IOException ex) {} alerta.setTimeout(Alert.FOREVER); display.setCurrent(alerta); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }

Listagem 4: Construtores da classe Alert.

Method Summary
void addCommand(Command cmd)

Similar ao
Displayable.addCommand(javax.microedition.lcdui.Command),

entretanto, quando a aplicao adiciona um comanndo para o Alert, o DISMISS_COMMAND removido automaticamente.
int getDefaultTimeout()

Retorna o tempo padro que um Alert ficar visvel.


Image getImage()

Retorna a imagem usada no Alert.


Gauge getIndicator()

Retorna o indicador associado ao Alert.


String getString()

Retorna o texto usado no Alert.


int getTimeout()

Retorna o tempo que o Alert ficar visvel.


AlertTy getType() pe Retorna o

tipo do Alert.

void removeCommand(Command cmd)

Similar a
Displayable.removeCommand(javax.microedition.lcdui.Command), entretanto, quando a aplicao remove um comando do lert, o DISMISS_COMMAND automaticamente adicionado. void setCommandListener(CommandListener l)

O mesmo que
Displayable.setCommandListener(javax.microedition.lcdui.Comma ndListener). void setImage(Image img)

Configura a instncia de Image a ser usada no Alert.


void setIndicator(Gauge indicador)

Configura um indicador para o Alert.


void setString(String str)

Configura o texto que ser usado no Alert.


void setTimeout(int time)

Configura o tempo que o Alert dever ficar visvel.


void setType(AlertType type) Configura o tipo do Alert.

A maioria dos mtodos da classe so auto-explicativos, porm, dois deles merecem um tratamento a parte. O mtodo setType recebe por

parmetro uma instncia da classe javax.microedition.lcdui.AlertType. Esta classe tem cinco constantes: ALARM, CONFIRMATION, ERROR, INFO e WARNING. Uma delas ser passada para o mtodo. Este tipo configura um som que executado quando o Alert mostrado ao usurio. A classe AlertType tambm permite que um som seja executado aleatoriamente, em qualquer parte do aplicativo. Para isso, basta usar o mtodo playSound(Display d), como mostra a linha de cdigo abaixo:
AlertType.WARNING.playSound(display);

O mtodo setIndicator associa ao Alert um objeto da classe javax.microedition.lcdui.Gauge. Este item ser visto detalhadamente mais adiante, se preferir, o leitor pode dar uma lida na descrio do item agora e tentar implementar este mtodo. Lembrando que ele est presente somente a partir da MIDP 2.0. 9.2 TextBox A classe javax.microedition.lcdui.TextBox apresenta ao usurio uma caixa de texto, semelhante ao componentes JTextArea presente na plataforma Java SE. Seu nico construtor recebe o ttulo, uma String que pode ser o texto inicial do componente, o tamanho mximo de caracteres que rea de texto suportar, e, por fim, recebe um inteiro que representa a constante de mscara do texto. Esta mscara uma das constantes presentes na classe javax.microedition.lcdui.TextField. Todas mscaras sero tratadas posteriormente, porm, para fins didticos, cito aqui algumas para facilitar o entendimento: ANY (qualquer texto), PASSWORD (o texto digitado se transforma em um caracter definido pela JVM, geralmente o *) e URL (a caixa de texto s aceita a entrada de um texto no formato de URL).

Construtor da classe TextBox


TextBox(String ttulo, String texto, int tamanhoMax, int mascara) Cria um novo objeto TextBox com um ttulo, texto, tamanho mximo e mscara

recebidos por parmetro.

A Figura 12 ilustra o componente gerado pelo cdigo representado na Listagem 5. importante ressaltar que somente o mtodo startApp sofreu alteraes, por isso, a Listagem 4 pode ser usada, trocando somente o mtodo referido anteriormente.

Figura 14: Exemplo do componente TextBox.


private Display display; private TextBox txbAnotacoes; private Command cmSair; public void startApp() { display = Display.getDisplay(this); txbAnotacoes = new TextBox("Anotaes: ", "", 200, TextField.ANY); display.setCurrent(txbAnotacoes); }

Listagem 5: Cdigo necessrio para gerar um TextBox.

Mtodos da classe TextBox


void delete(int inicio, int tamanho)

Deleta os caracteres especificados do inicio e com um tamanho fixo.


int getCaretPosition()

Retorna a posio corrente do cursor.


int getChars(char[] data)

Copia o contedo do TextBox para um vetor de caracteres.


int getConstraints()

Recupera a mscara em uso do TextBox.


int getMaxSize()

Retorna o tamanho mximo (nmero de caracteres) que podem ser armazenados no TextBox.
String getString()

Recupera o contedo do TextBox.


void insert(char[] data, int indice, int tamanho, int posicao) Insere dados de um array de caracteres, especificando o indice e o tamanho a ser copiado. O parmetro posicao indica o ndice do TextBox

que

receber o novo texto.


void insert(String src, int posicao)

Insere uma string no contedo de texto do TextBox, especificando a


posio. void setChars(char[] data, int inicio, int tamanho) Configura o contedo do TextBox a partir de um vetor de caracteres.. void setConstraints(int mascara)

Configura a mscara de entrada de dados do TextBox.


int setMaxSize(int tamanhoMaximo)

Configura o tamanho mximo (nmero de caracteres) que o TextBox suporta.


void setString(String texto)

Configura o contedo do TextBox.


void setTicker(Ticker ticker)

Configura um item ticker a ser usado pelo Displayable.


void setTitle(String titulo) Configura o ttulo do Displayable. int size()

Retorna o nmero de caracteres que esto armazenados no TextBox.

Assim como o Alert, as classes do TextBox so fceis de entender, porm, para facilitar a vida do leitor, a Listagem 6 apresenta uma classe que mostra um TextBox e faz diversas alteraes no componente a cada vez que o Command pressionado.

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class CicloVida extends MIDlet implements CommandListener{ private Display display; private TextBox txbAnotacoes; private Command cmPosicao; int aux = 0; public void startApp() { display = Display.getDisplay(this); txbAnotacoes = new TextBox("Anotaes: ", "Texto inicial", 200, TextField.ANY); cmPosicao = new Command("Command", Command.ITEM, 1); txbAnotacoes.addCommand(cmPosicao); txbAnotacoes.setCommandListener(this); display.setCurrent(txbAnotacoes); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command arg0, Displayable arg1) { if (aux == 0) txbAnotacoes.delete(5, 8); else if (aux == 1) System.out.println("Posio: "+txbAnotacoes.getCaretPosition()); else if (aux == 2) txbAnotacoes.insert(" alterado", 5); else if (aux == 3) txbAnotacoes.setChars(new String("Novo texto").toCharArray(), 0, 10); else if (aux == 4) txbAnotacoes.setConstraints(TextField.PASSWORD); else if (aux == 5) txbAnotacoes.setTicker(new Ticker("Ticker para o TextBox")); aux++; } }

Listagem 6: Classe que manipula o componente TextBox.

A Figura 13 apresenta o resultado do cdigo. importante perceber na parte superior do TextBox, ao contrrio da Figura 12, aparece um texto, que faz parte do Ticker que foi adicionado com o mtodo setTicker. Mais sobre este item posteriormente. O texto do componente tambm apresentado com uma mscara de senha, isso aconteceu depois da linha de cdigo setConstraint(TextField.PASSWORD).

Figura 15: Tela resultante da Listagem 5.

9.3 List A classe javax.microedition.lcdui.List permite que o desenvolvedor apresenta uma lista para o usurio. A classe apresenta dois construtores: pode-se construir uma lista vazia passando apelas o ttulo da lista e o seu tipo, ou, passamos ainda um vetor de strings e um vetor de imagens, que formaro os itens da lista. Independente do construtor, os itens da lista podem ser rearranjados de vrias maneiras mesmo depois da inicializao do componente, atravs dos mtodos insert, delete, deleteAl e set. Quanto ao tipo da List, ela pode ser referenciada com uma das trs constantes oferecidas pela classe: EXCLUSIVE: permite que somente um item seja selecionado a cada vez. MULTIPLE: permite a seleo de vrios itens da lista.

IMPLICIT: cada seleo de item dispara um evento que pode ser capturado pelo ComandListener da classe.

Construtores da classe List


List(String titulo, int tipoLista) Cria um novo objeto List vazio, especificando

somente o ttulo e o tipo da lista. um vetor de

List(String titulo, int tipoLista, String[] elementos, Image[] iconesElementos) Cria um novo objeto List, especificando o ttulo, o tipo da lista,

Strings e imagens que compes os itens da lista.

Method Summary
int append(String string, Image imagem) Adiciona um novo item ao objeto List. void delete(int indice)

Deleta o elemento referenciado pelo indice.


void deleteAll()

Deleta todos os elementos da lista.


Font getFont(int indice)

Retorna a fonte usada pela aplicao de um elemento especifcado pelo parmetro recebido.
Image getImage(int indice) Retorna o objeto Image indice.

de um elemento especfico referenciado pelo

int getSelectedFlags(boolean[] arrayRetorno) Armazena o estado dos elementos do List no

array recebido por

parmetro.
int getSelectedIndex()

Retorna o nmero do ndice do elemento que est selecionado na lista.


String getString(int indice) Retorna a String do

elemento referenciado por indice.

void insert(int indice, String parteString, Image parteImagem) Insere um elemento na lista, colocando ele no ndice.. boolean isSelected(int indice)

Verifica se o elemento do indice est selecionado ou no.


void removeCommand(Command cmd) O mesmo que Displayable.removeCommand. void set(int indice, String stringPart, Image imagePart) Configura o String e a Image de um elemento da lista, referenciado pelo ndice. void setFont(int indice, Font font)

Configura a fonte de um elemento da lista.


void setSelectedFlags(boolean[] arraySelecionados)

Configura o estado de todos os itens da lista.


void setSelectedIndex(int indice, boolean selecionado) Configura o estado de um indice para selecionado ou void setTicker(Ticker ticker)

no.

Configura um ticker para usar com este Displayable.


void setTitle(String s)

Configura o ttulo do Displayable.


int size()

Recupera o nmero de elementos do List.

Os mtodos da classe List so auto-explicativos, pois seguem basicamente o mesmo padro dos outros componentes. A Listagem 7 ajudar o leitor a fixar alguns dos principais mtodos. As Figuras que se encontro logo abaixo do cdigo representam o comportamento do componente aps a execuo de cada mtodo:
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ExList extends MIDlet implements CommandListener{ private Display display; private List lsMain; private Command cmSeleciona; public void startApp() { display = Display.getDisplay(this); cmSeleciona = new Command("Seleciona", Command.ITEM, 1); lsMain = new List("Frutas:", List.IMPLICIT, new String[]{"Uva", "Melo", "Melancia"}, null); /*lsMain.delete(2); lsMain.insert(1, "Melancia", null); lsMain.set(1, "Pera", null); lsMain.append("Maa", null); lsMain.setFont(0, Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_LARGE));*/ lsMain.addCommand(cmSeleciona); lsMain.setCommandListener(this); display.setCurrent(lsMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command c, Displayable d) { } }

Listagem 7: Classe que manipula o componente List.

Figura 16: Lista inicial.

Figura 17: Lista aps a execuo do mtodo lsMain.delete(2).

Figura 18: Lista aps a execuo do mtodo lsMain.insert.

Figura 19: Lista aps a execuo do mtodo lsMain.set(1, "Pera", null).

Figura 20: Lista aps a execuo do mtodo lsMain.append("Maa", null).

Figura 21: Lista aps a execuo do mtodo lsMain.setFont().

10. Interface Grfica de Alto Nvel Form A classe javax.microedition.lcdui.Form merece um captulo a parte, isso porque o componente pode agregar outros componentes, que so chamados de itens. Uma analogia um quadro de recados, onde qualquer pessoa pode colocar um lembrete, uma foto, ou qualquer outra coisa, somente grudando no quadro. A tabela abaixo apresenta os dois construtores da classe.

Construtores da classe Form


Form(String titulo)

Cria um novo objeto Form, somente com o titulo.


Form(String titulo, Item[] items) Cria um novo objeto Form, especificando

seu titulo e seus itens iniciais.

O primeiro construtor cria um objeto Form somente com ttulo, sem nenhum item inicial. O segundo construtor permite que o programador passe um vetor com instncias da classe javax.microedition.lcdui.Item. Indiferente do mtodo usado, a classe fornece meios de adicionar ou remover qualquer Item em qualquer momento. A tabela abaixo apresenta os principais mtodos da classe.

Principais mtodos da classe Form


int append(Image img)

Adiciona um item da classe Image para o Form.


int append(Item item) Adiciona um Item int append(String str)

dentro do Form.

Adiciona um item String para o Form.


void delete(int indiceItem) Deleta um Item refeenciado void deleteAll()

pelo seu indice.

Deleta todos os itens do Form, deixando-o com zero itens.


Item get(int indiceNum)

Recupera o item de um dado ndice.


int getHeight()

Returns the height in pixels of the displayable area available for items.
int getWidth()

Returns the width in pixels of the displayable area available for items.
void insert(int itemNum, Item item) Inserts an item into the Form just void set(int itemNum, Item item)

prior to the item specified.

Sets the item referenced by itemNum to the specified item, replacing the previous item.
void setItemStateListener(ItemStateListener iListener) Sets the ItemStateListener for the Form, replacing any previous ItemStateListener. int size()

Gets the number of items in the Form.

Os mtodos seguem o padro das outras classes, ou seja, so intuitivos. Uma considerao sobre a diferena entre os mtodos append e insert, porm, bem vinda. O primeiro adiciona o Item logo abaixo dos demais, ou seja, se o formulrio contm cinco itens, o novo ser adiciona logo aps o quinto elemento. Porm, o mtodo insert coloca o novo item na posio especifica pelo parmetro recebido, ou seja, se passarmos 0, o novo item ser inserido na primeira posio. importante perceber tambm a importncia do mtodo setItemStateListener. Diferentemente dos outros componentes vistos at agora, o Form pode conter um listener que verifica quando um dos seus itens foi modificado. Quando uma classe implementa a interface javax.microedition.lcdui.ItemStateListener, deve, obrigatoriamente, implementar tambm o mtodo itemStateChanged(Item item). A Listagem 8 apresenta trechos de cdigo da classe ExForm, que implementa o listener ItemStateListener. A primeira linha traz o primeiro ponto crucial, que o implements ItemStateListener. Isso faz com que a classe possa ficar escutando as possveis alteraes nos itens associados a um Form. O segundo ponto o uso do mtodo setItemStateListener(MIDlet midlet) em um formulrio. O Item ChoiceGroup vai ser detalhado posteriormente. Com a implementao da interface ItemStateListener obrigatrio o uso do mtodo itemStateChanged(Item item). O parmetro recebido serve para que o programador possa implementar uma funcionalidade para cara Item que aciona o listener.

public class ExForm extends MIDlet implements ItemStateListener{ ... public void startApp() { display = Display.getDisplay(this); fmMain = new Form("Formulrio"); cgFruta = new ChoiceGroup("Fruta: ", Choice.POPUP, new String[]{"Melo", "Uva", "Melancia", "Maa"}, null); fmMain.setItemStateListener(this); fmMain.append(cgFruta); display.setCurrent(fmMain); } ... public void itemStateChanged(Item item) { if (item == cgFruta) System.out.println("O ChoiceGroup foi alterado"); }

Listagem 8: Trecho de cdigo da classe ExForm que implementa a ItemStateListener.

10.1 Itens A classe javax.microedition.lcdui.Item possui subclasse que podem ser adicionadas em instncias das classe Form e Alert. No total so oito subclasses: ChoiceGroup, CustomItem, DateField, Gauge, ImageItem, Spacer, StringItem e TextField. Todos estes componentes possuem dois mtodos herdados de sua superclasse, que so getLabel() e setLabel(String rotulo). O rtulo de um componente geralmente fica na extremidade esquerda do mesmo, porm, esse comportamento pode variar de implementao para implementao. A Figura 22 ilustra os itens que podem ser acoplados a um objeto da classe Form.

Figura 22: Itens presentes na MIDP 2.0 que podem ser usados dentro de um objeto da classe Form. Retirado de: http://www.devx.com/wireless/Article/21262/1954

Mtodos da classe Item


String getLabel()

Retorna o rtulo do objeto Item.


void setLabel(String rotulo)

Configura o rtulo do objeto Item.

10.2 ChoiceGroup A classe permite que o programador apresente um grupo de escolha ao usurio. Seu construtor recebe os mesmo parmetros que a classe List, ou seja, um rtulo, seu tipo, e (opcionalmente) uma lista de itens prconfigurados para o componente. Uma diferena sutil, porm importantssima, tem relao a seu tipo. No List o programador pode usar a constante IMPLICIT para configurar um evento automaticamente assim que o objeto sofrer modificaes, j no ChoiceGroup, as opes disponveis so: MULTIPLE (mltipla escolha), EXCLUSIVE (apenas um item selecionado por vez) e POPUP (os itens so apresentados em uma janela popup).

Para ilustrar melhor oque seria um ChoiceGroup, e at mesmo o tipo POPUP, vejam as Figuras 23 e 24. A primeira apresenta os trs tipos possveis do item, sendo eles do primeiro para o ltimo: EXCLUSIVE, POPUP e MULTIPLE. Notem que no ltimo tipo os dois combos esto selecionados. A Figura 23 mostra o ChoiceGroup POPUP selecionado.

Figura 23: ChoiceGroup e seus tipos.

Figura 24: ChoiceGroup Popup selecionado.

importante ressaltar que os componentes MIDP no oferecem um comportamento grfico homogneo em todas as plataformas em que so executadas. Usando o exemplo do ChoiceGroup, veja a Figura 25, que traz a execuo do mesmo aplicativo, porm, em um emulador de um telefone celular da Samsung. Perceba que o segundo choice, que do tipo POPUP est selecionado, tendo um comportamento completamente diferente daquele emulado pelo Wireless Toolkit.

Figura 25: ChoiceGroup Popup selecionado no emulador do SGH-X800 da Samsung.

Construtores da classe ChoiceGroup


ChoiceGroup(String rotulo, int tipo)

Cria um novo ChoiceGroup vazio, especificando seu ttulo e seu tipo.


ChoiceGroup(String rotulo, int tipo, String[] elementosString, Image[] elementosImagem)

Cria um novo ChoiceGroup, especificando seu ttulo, o tipo e um vetor com strings e imagens eu formam os elementos do componente.

Os mtodos da classe ChoiceGroup apresentam o mesmo comportamento da classe List.

Principais mtodos da classe ChoiceGroup

int append(String texto, Image imagem)

Adiciona um novo elemento ao Choice.


void delete(int indice)

Deleta o elemento referenciado pelo seu ndice.


Image getImage(int indice)

Retorna um objeto Image do elemento referenciado pelo ndice.


int getSelectedFlags(boolean[] arrayRetorno)

Recupera o estado dos elementos de um ChoiceGroup, armazendo-os em um vetor de booleanos recebido por parmetro.
int getSelectedIndex()

Retorna o ndice do elemento que est selecionado atualmente.


String getString(int indice)

Retorna o texto do elemento referenciado pelo seu ndice.


void insert(int indice, String texto, Image imagem)

Insere um elemento dentro do Choice no ndice especificado por parmetro.


boolean isSelected(int indice)

Retorna um valor booleano indicando se o ndice do parmetro est selecionado ou no.


void set(int indice, String texto, Image imagem)

Configura o elemento referenciado pelo sue ndice, atualizando seu texto e sua imagem com os parmetros recebidos.
void setSelectedFlags(boolean[] arraySelecionado)

Tenta configurar o estados de cada elemento de um ChoiceGroup.


void setSelectedIndex(int indice, boolean selecionado)

Para objetos ChoiceGroup do tipo MULTIPLE, ele simplesmente configura o estado de um elemento individualmente.
int size()

Retorna o nmero de elementos presentes no ChoiceGroup.

10.3 StringItem A classe javax.microedition.lcdui.StringItem fornece ao desenvolvedor um componente de apresentao de texto. Este componente passou a apresentar iterao com o usurio somente a partir da MIDP 2.0, atravs de seu construtor que recebe um inteiro chamado de appearance mode, ou, um inteiro que define o design do item. bom lembrar, que o comportamento visual de todos os itens no homogneo em todos os dispositivos. As opo so: PLAIN: Nenhuma alterao apresentada, o StringItem padro apresentado. BUTTON: O StringItem ganha o formato de um boto. Alm disso, o mesmo pode contar um ItemCommandListener para

capturar as aes do usurio. Desta maneira, o StringItem ganha forma e comportamento de um boto. HYPERLINK: O StringItem recebe o formato de um hyperlink. Alm disso, tambm pode conter a ItemCommandListener. O outro construtor da classe no especifica o comportamento de aparncia do item, somente passa como parmetro seu rtulo e o seu texto. A aparncia recebe, por padro, a opo PLAIN. A Figura 26 apresenta trs tipos de StringItem, sendo eles: um para o nome do usurio (BUTTON), um para a idade (PLAIN) e, finalmente, um para a cidade (KYPERLINK). Perceba que a Figura 27 apresenta os mesmos StringItens porm, a apresentao difere do emulador ao lado. Isso acontece pela falta de padronizao das JVMs presentes nos dispositivos, gerando interfaces dispares em aparelhos de plataformas diferentes. Porm, o comportamento e as funes dos componentes continua inalterada.

Figura 26: Exemplos de StringItem no emulador do WTK da Sun

Figura 27: Exemplos de StringItem no emulador do Nokia 6165.

A Listagem 9 apresenta o cdigo necessrio para criar o aplicativo que apresentado nas Figuras 26 e 27. Perceba que necessrio a criao de um objeto do tipo Command, para ser utilizado nos StringItem que no so do tipo PLAIN. Alm disso, um listener deve ser adicionado a cada um destes itens, atravs do mtodo setItemCommandListener. Posteriormente, no mtodo commandAction(Command, Item) possvel configurar a ao referente a cada StringItem.
public class ExStringItem extends MIDlet implements ItemCommandListener{ private Display display; private static final Command CMD_PRESS = new Command("Press", Command.ITEM, 1); private StringItem siNome, siIdade, siCidade; private Form fmMain; public void startApp() { display = Display.getDisplay(this); siNome = new StringItem("Nome:", "Ricardo da Silva Ogliari", Item.BUTTON); siNome.setDefaultCommand(CMD_PRESS); siNome.setItemCommandListener(this); siCidade = new StringItem("Cidade:", "Passo Fundo", Item.HYPERLINK); siCidade.setDefaultCommand(CMD_PRESS); siCidade.setItemCommandListener(this); siIdade = new StringItem("Idade:", "23", Item.PLAIN); fmMain = new Form("Ex. StringItem"); fmMain.append(siNome); fmMain.append(siIdade); fmMain.append(siCidade); display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command arg0, Item arg1) { throw new UnsupportedOperationException("Not supported yet."); } }

Listagem 9: Trecho de cdigo da classe ExStringItem que apresenta a forma de utilizao do item.

Abaixo, seguem as tabelas de construtores respectivamente. Os mtodos so auto-explicativos.

mtodos,

Construtores da classe StringItem

StringItem(String rotulo, String texto) Cria um novo objeto StringItem. StringItem(String label, String text, int appearanceMode) Cria um novo StringItem com um rtulo, texto e aparncia.

Mtodos da classe StringItem


int getAppearanceMode()

Retorna o modo de aparncia do StringItem.


Font getFont()

Retorna a fonte usada no momento pelo StringItem.


String getText()

Retorna o contedo de texto do StringItem, ou null se o StringItem est vazio.


void setFont(Font fonte)

Configura a fonte utilizada pelo StringItem.


void setPreferredSize(int largura, int altura) Configura a largura e altura preferencial do Item. void setText(String texto)

Configura o contedo de texto do StringItem.

10.4 TextField A classe javax.microedition.lcdui.TextField permite ao desenvolvedor a utilizao de um componente de entrada de texto padro. Seu nico contrutor especifica o rtulo que ficar (geralmente) no lado esquerdo do componente, um texto inicial (pode ser configurado como uma string vazia, quando o desenvolvedor no deseja nenhum texto padro), um tamanho mximo de caracteres que o campo ir possuir e, finalmente, uma constraint, que funciona como uma mscara. Para conhecer o componente pessoalmente, veja as Figuras 28 e 29.

Figura 28: Exemplos de TextField no emulador do Motorola RAZR

Figura 29: Exemplos de TextField no emulador do WTK da Sun

O conceito de constraint merece uma ateno especial. A classe apresenta constantes que definem estes valores, as principais so mostradas a seguir: ANY: permite a entrada de qualquer texto. DECIMAL: o usurio pode informar valores decimais, por exemplo "-123", "0.123", or ".5". EMAILADDR: o usurio pode informar valores no formato de email. NUMERIC: o usurio pode inserir somente valores numricos. PASSWORD: indica que o texto confidencial, geralmente, os caracteres digitados so mostrados no visor de telefone celular como um caracter especial (*). PHONENUMBER: o usurio informa um nmero de telefone. Em algumas implementaes da Java ME, um campo deste tipo, permite o acesso a agenda de telephone fo aparelho. URL: o usurio insere uma URL.

Por exemplo, se um novo campo senha for colocado na aplicao mostrada nas Figuras 28 e 29, e seu constraints for definido como PASSWORD, e, o usurio digite uma senha 12345, ele ver no display do seu telefone celular uma tela semelhante a da Figura 30.

Figura 30: Exemplos de TextField com um campo tipo PASSWORD

Abaixo, segue o construtor e os principais mtodos da classe TextField. A Listagem 10, por sua vez, apresenta o cdigo fonte necessrio para produzir a aplicao mostrada na Figura 30.

Construtor da classe TextField


TextField(String label, String texto, int tamanhoMaximo, int constraints) Cria um novo objeto TextField com um rtulo, texto inicial, tamanho

mximo

de caracteres e uma mscara.

Principais mtodos da classe TextField


void delete(int inicio, int tamanho) Deleta caracteres do TextField. int getCaretPosition()

Pega a posio de input corrente.


int getChars(char[] data)

Copia o contedo do TextField para um vetor de caracteres, comeando do ndice zero.


int getConstraints()

Retorna o constraints (mscara) corrente do TextField.


int getMaxSize()

Retorna o tamanho mximo (nmero de caracteres) que pode ser armazenado no TextField.
String getString()

Retorna o contedo do TextField como um valor de String.


void insert(char[] dados, int inicio, int tamanho, int posicao) Insere uma parte de um vetor de caracteres no contedo do TextField. void insert(String texto, int posicao) Insere uma string no contedo do TextField. void setChars(char[] dados, int incio, int tamanho) Configura o contedo do TextField a partir de um vetor de caracteres,

sobrepondo o contedo prvio.


void setConstraints(int constraints)

Configura o constraint (mscara) do TextField.


int setMaxSize(int tamanhoMaximo)

Configura o tamanho mximo (nmero de caracteres) que o component epode conter.


void setString(String texto)

Configura o contedo do TextField como um valor String, substituindo o contedo prvio.


int size()

Recupera o nmero de caracteres que esto armazenados no


TextField.

public class ExTextField extends MIDlet { private Display display; private Form fmMain; private TextField tfNome, tfSobrenome, tfSenha; public void startApp() { display = Display.getDisplay(this); tfNome = new TextField("Nome:", "", 100, TextField.ANY); tfSobrenome = new TextField("Sobrenome:", "", 100, TextField.ANY); tfSenha = new TextField("Senha:", "", 5, TextField.PASSWORD); fmMain = new Form("Usurio"); fmMain.append(tfNome); fmMain.append(tfSobrenome); fmMain.append(tfSenha); display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }

Listagem 10: Trecho de cdigo da classe ExTextField que apresenta a forma de utilizao do TextField.

10.5 DateField A classe javax.microedition.lcdui.DateField permite que o programador apresente ao usurio um componente de seleo de data e tempo. Seu primeiro construtor o rtulo e seu modo. O modo representado por uma das duas constantes da classe: DATE: somente edio da data. DATE_TIME: edio de data e hora. O seu modo difere na interface visual do componente e na sua funo. As Figura 31 apresenta os dois componentes, o primeiro do tipo DATE, e, o ltimo DATE_TIME. A mesma figura pode ser utilizada para explicar o conceito de TimeZone. Perceba que a Figura apresenta dois componentes com data e hora, o primeiro apresenta a hora local (03:54) e o segundo apresenta a data e hora do local de destino de viagem (Denver, 08:54).

Figura 31: Exemplos de componente DateField DATE e DATE_TIME.

A Listagem 11 mostra o cdigo necessrio para a instanciao dos dois ltimos componentes. Perceba que o segundo operador new define o TimeZone do componente como GMT-07:00. Posteriormente, os dois componentes so configurados com a mesma data, porm, percebe-se claramente que a data do DateField do horrio local difere da data do DateField do horrio em Denver.
dfDataHora = new DateField("Viagem Hor. Local:", DateField.DATE_TIME); dfDataHoraTimeZone = new DateField("Viagem Hor. Denver:", DateField.DATE_TIME, TimeZone.getTimeZone("GMT-07:00")); dfDataHora.setDate(new Date()); dfDataHoraTimeZone.setDate(new Date());

Listagem 11: Trecho de cdigo que apresenta a criao de configurao dos dois componentes DateField DATE_TIME.

Abaixo, segue os dois construtores da classe DateField, seguido de seus principais mtodos.

Construtores da classe DateField


DateField(String rotulo, int modo) Cria um novo objeto DateField com

seu rtulo e modo especfico.

DateField(String rotulo, int modo, TimeZone timeZone)

Cria um novo objeto, onde o clculo do calendrio baseado em um objeto TimeZone especfico. Padronizando o sistema de calendrio para local corrente especificado.

Principais mtodos da classe DateField


Date getDate()

Retorna o valor do campo.


int getInputMode()

Retorna o modo do DateField.


void setDate(Date date)

Configura um novo valor para o campo.


void setInputMode(int mode)

Configura um novo modo para o campo de data.

Um dos pontos importantes a ser percebido, o fato de sua falta de padronizao de interface entre as plataformas de implementao da Java ME. Pode-se dizer que o componente MIDP que apresenta a maior falta de semelhana entre suas implementaes, sendo assim, no fique assustado se seu aplicativo tiver uma cara em um emulador e, quando for transposto para um telefone celular real, tiver uma cara totalmente diferente. Na tabela abaixo esto presentes os emuladores da Srie 80 dos telefones Nokia, LG 160 e emulador padro do Sun Wireless Toolkit.

Figura 32: Exemplos de DateField no emulador da Srie 80 da Nokia.

Figura 33: Exemplos de edio de um componente DateField no emulador da Srie 80 da Nokia.

A Figura 32 e 33 apresenta o DateField sendo executado em um emulador do Nokia srie 80. Perceba que alm da mudana de interface, sua edio de d de duas maneiras. A primeira, consiste na digitao da data e da hora, a segunda, acessando o componente, neste momento, uma tela pop-up aberta e a data pode ser escolhida dentro de um calendrio grfico. A escolha da hora no possui a escolha do pop-up. A Figura 34 apresenta o DateField em um emulador do LG 160. Sua interface grfica j sofreu uma grande diferena em relao aquela apresentada na Figura 32.

Figura 34: Exemplos do componente DateField no emulador do aparelho LG 160.

Figura 35: Exemplo de edio do componente DateField (modo DATE) no emulador do aparelho LG 160.

Figura 36: Exemplo de edio do componente DateField (modo DATE_TIME) no emulador do aparelho LG 160.

As Figuras 35 e 36 nos do uma noo exata da falta de padronizao da interface grfica do DateField. No primeira, apresentada a tela de edio do componente quando seu modo DATE, por sua vez, a Figura 36 ilustra a tela de edio do DateField com o seu modo configurado para DATE_FIELD. Lembrando que o programador no teve que digitar nenhuma linha de cdigo para que o calendrio e o relgio analgico fossem mostrados ao usurio, somente usou o operador new e passou os parmetros necessrios ao construtor da classe. A Figura 36 apresenta a tela que edita a hora do componente DateField (modo DATE_FIELD), no emulador da Sun. Lembrando que a interface padro do componente no mesmo emulador mostrada na Figura 31. A Figura 37 ilustra a edio da data do DateField.

Figura 36: Exemplo de edio da hora do componente DateField no emulador da Sun.

Figura 37: Exemplo de edio da data do componente DateField no emulador da Sun.

A Listagem 12 apresenta o cdigo necessrio para criao da aplicao que foi mostrada nos exemplos do componente TextField.

import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ExDateField extends MIDlet { private Display display; private DateField dfDataHora, dfDataHoraTimeZone, dfData; private Form fmMain; public void startApp() { display = Display.getDisplay(this); dfData = new DateField("Aniversrio:", DateField.DATE); dfDataHora = new DateField("Viagem Hor. Local:", DateField.DATE_TIME); dfDataHoraTimeZone = new DateField("Viagem Hor. Denver:", DateField.DATE_TIME, TimeZone.getTimeZone("GMT-07:00")); dfData.setDate(new Date()); dfDataHora.setDate(new Date()); dfDataHoraTimeZone.setDate(new Date()); fmMain = new Form("Viagem"); fmMain.append(dfData); fmMain.append(dfDataHora); fmMain.append(dfDataHoraTimeZone); display.setCurrent(fmMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} }

Listagem 12: Classe de exemplo de uso do componente DateField.

10.5 ImageItem A classe javax.microedition.lcdui.ImageItem permite a utilizao de um componente que tem como funo bsica, mostrar uma imagem no display do aparelho do usurio. Os dois construtores recebem quatro parmetros padro: um valor String que ser o rtulo do componente (geralmente fica no lado esquerdo), uma instncia de um objeto Image que define a imagem propriamente dita, um inteiro que define o layout do componente um texto alternativo que pode substituir a imagem. O construtor mais extenso, tambm recebe um inteiro, que define a sua aparncia, semelhante ao que ocorre com o componente StringItem (esse construtor est presente s na verso da MIDP 2.0 e superiores).

Construtores da classe ImageItem


ImageItem(String rotulo, Image imagem, int layout, String textoAlternativo) Cria um novo objeto ImageItem com um rtulo, uma imagem,

um layout e um

texto alternativo.
ImageItem(String rotulo, Image imagem, int layout, String textoAlternativo, int modoAparencia) Cria um novo objeto ImageItem com um rtulo, uma imagem,

um layout, um texto alternativo e um valor inteiro que define seu modo de aparncia.

Quando um objeto da classe Image utilizado para criar o objeto ImageItem, o programador tem duas opes: pode utilizar uma imagem mutvel ou imutvel. Uma imagem imutvel carregada da prpria aplicao, ou seja, um arquivo com extenso .png que foi empacotada junto com o arquivo. .jar da aplicao, ou ainda, uma imagem que buscada em uma pgina web. Imagem mutvel criada de dentro da aplicao, o programador utiliza a seguinte linha de cdigo:
Image teste = Image.createImage(30, 30); Graphics g = teste.getGraphics();

A classe Image possui duas maneiras de criar um objeto do seu tipo, um deles atravs do mtodo createImage(int largura, int altura)(mutvel), e o outro, passando o endereo da imagem (imutvel). Depois de criado o objeto, possvel obter uma instncia da classe Graphics. Imagens mutveis utilizam de um objeto Graphics, para desenhar diretivas grficas que formam a imagem. Posteriormente, esta classe ser discutida com maiores detalhes. No momento, basta saber que uma imagem imutvel criada pelo prprio programador atravs de suas diretivas grficas, porm, o meio mais comum a criao de imagens imutveis atravs de um arquivo externo. O inteiro que define o layout da imagem (terceiro parmetro do construtor) pode ser definido com uma das constantes da classe, os mais comuns so: LAYOUT_LEFT: alinha o componente esquerda da tela. LAYOUT_CENTER: alinha o componente no centro da tela. LAYOUT_RIGHT: alinha o componente direita da tela. A Figura 37 mostra os trs layout em ao. O segundo construtor apresentado, tambm recebe um valor inteiro que especifica o seu modo de aparncia, utilizando a mesma idia que aplicada ao componente StringItem, visto anteriormente. No total, trs constantes podem ser utilizadas;

PLAIN: padro, no altera o formato do ImageItem. BUTTON: o ImageItem recebe o formato aproximado de um boto, que pode variar de implementao para implementao, como pode ser visto nas Figuras 37 e 39: KYPERLINK: o ImageItem recebe o formato de um hyperlink, tambm sensitivo a implementaes da Java ME. Assim como no StringItem, necessrio a criao de um objeto do tipo Command, para ser utilizado nos ImageItems que no so do tipo PLAIN. Alm disso, um listener deve ser adicionado a cada um destes itens, atravs do mtodo setItemCommandListener. Posteriormente, no mtodo commandAction(Command, Item) possvel configurar a ao referente a cada ImageItem. Veja a Listagem 13 para entender como isso funciona e tambm para visualizar o cdigo fonte necessrio para criar o aplicativo das Figuras 37, 38, 39 e 40. Abaixo, segue os principais mtodos da classe ImageItem.

Principais mtodos da classe ImageItem


String getAltText()

Gets the text string to be used if the image exceeds the device's capacity to display it.
int getAppearanceMode()

Returns the appearance mode of the ImageItem.


Image getImage()

Gets the image contained within the ImageItem, or null if there is no contained image.
int getLayout()

Gets the layout directives used for placing the image.


void setAltText(String text)

Sets the alternate text of the ImageItem, or null if no alternate text is provided.
void setImage(Image img) Sets the Image object void setLayout(int layout)

contained within the ImageItem.

Sets the layout directives.

import java.io.IOException; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ExImageItem extends MIDlet implements ItemCommandListener { private Display display; private ImageItem imgEs, imgDi, imgCentro; private Image img; private Form fmMain private Command cmMsg; public void startApp() { display = Display.getDisplay(this); fmMain = new Form("Ex. ImageItem"); cmMsg = new Command("Sair", Command.EXIT, 1); try { img = Image.createImage("/imagem.png"); imgEsq = new ImageItem("Imagem: ", img, Item.LAYOUT_LEFT, ""); imgCentro = new ImageItem("Imagem: ", img, Item.LAYOUT_CENTER, "", Item.BUTTON); imgCentro.setDefaultCommand(cmMsg); imgCentro.setItemCommandListener(this); imgDir = new ImageItem("Imagem: ", null, Item.LAYOUT_RIGHT, "Texto misteriorso", Item.HYPERLINK); imgDir.setDefaultCommand(cmMsg); imgDir.setItemCommandListener(this); } catch (IOException e) { // tratamento do erro } fmMain.append(imgEsq); fmMain.append(imgCentro); fmMain.append(imgDir); display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Item i) { if (i == imgCentro) display.setCurrent( new Alert("Mensagem", "Chamado pelo ImageItem do centro", null, AlertType.INFO)); else display.setCurrent( new Alert("Mensagem", "Chamado pelo ImageItem da direita", null, AlertType.INFO)); } }

Listagem 13: Classe de exemplo de uso do componente DateField.

Figura 37: Exemplo de ImageItem no emulador da Srie 80 dos telefones celulares da Nokia.

Figura 38: Exemplo de interao com ImageItem no emulador da Srie 80 da Nokia.

Figura 39: Exemplo de ImageItem no emulador do LG LX260.

Figura 40: Exemplo de interao com o ImageItem no emulador do LG LX260.

10.6 Gauge A classe javax.microedition.lcdui.Gauge se trata de um componente que pode ser interpretado e utilizado de diferentes maneiras. Pessoalmente, ele me lembra daqueles itens que so usados para configurao de nvel de jogo ou de volume, nos games de aparelhos celulares. Para decidir sobre oque voc acha, veja Figura 41. O Gauge recebe um valor mximo e um valor mnimo, que definem sua apresentao, por exemplo, no exemplo da Figura 40 seu valor corrente est configurado com 10, e seu valor inicial

com 0. J na Figura 41, o mesmo componente aparece com valor corrente igual a 5. Seu construtor recebe quatro parmetros: um rtulo (geralmente fica ao lado esquerdo do componente), um valor booelano que indica se seu contedo pode ser alterado diretamente pelo usurio ou no, e por fim, dois inteiros, que definem seu valor mximo e valor inicial, respectivamente.

Construtores da classe Gauge


Gauge(String rotulo, boolean interativo, int valorMaximo, int valorInicial) Cria um novo objeto Gauge com um rtulo, um booleano que indica se o

componente interativo ou no, seu valor mximo e seu valor inicial.

Algums questes sobre o componente devem ser discutidas, primeiramente, seu booleano interativo. Se o mesmo estiver como true, o usurio pode alterar o valor corrente do item, alterando em tempo real a aparncia visual. Caso contrrio, o valor pode ser alterado somente codificao. Na ltima maneira, geralmente implementada uma thread que implementar de forma automtica o valor. Este uso comum em telas de espera para conexo com a rede GPRS. Para compreender este conceiito de forma completa, veja as Listagens 14 e 15. O primeiro utiliza o Gauge interativo, ou seja, no seu construtor foi passado true no segundo parmetro. A ltima listagem apresenta o Gauge com uso de Thread. Perceba que a interface Runnable implementada, e seu preenchimento ocorre quando o Command cmInicia for selecionado. No mtodo run implementa-se um lao while, que executa at que o valor mximo do componente no for igual ao seu valor mximo. O uso dos mtodos getValue() e setValue(int valor) usado intensamente. A Listagem 14 produz um resultado mostrado na aplicao das Figuras 40 e 41. Abaixo segue a tabela com os principais mtodos da classe Gauge.

Principais mtodos da classe Gauge


void addCommand(Command cmd) Adiciona um Command para o

item (somente a partir da verso 2.0 do

perfil MIDP).
int getMaxValue()

Retorna o valor mximo que o objeto Gauge pode assumer.


int getValue()

Retorna o valor corrente do objeto Gauge.


boolean isInteractive()

Retorna um valor Boolean indicando se o item permite que o usurio modifique seu contedo.
void setDefaultCommand(Command cmd)

Configura o Command padro para o Item.


void setItemCommandListener(ItemCommandListener l) Configura um listener para os Commands do Item, substituindo qualquer outro ItemCommandListener. void setLabel(String rotulo) Configura o rtulo do Item. void setLayout(int layout)

Configura a diretiva de layout do componente.


void setMaxValue(int valorMaximo)

Configura o valor mximo do objeto Gauge.


void setPreferredSize(int largura, int altura)

Configura a largura e altura preferida para este Item.


void setValue(int valor)

Configura o valor corrente do objeto Gauge.


import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ExGauge extends MIDlet implements ItemCommandListener{ private Display display; private Form fmMain; private Gauge gVolume; private StringItem siVolume; private Command cmSair; public void startApp() { display = Display.getDisplay(this); fmMain = new Form("Configuraes de volume"); cmSair = new Command("Sair", Command.EXIT, 1); siVolume = new StringItem("Configurar Volume", null); gVolume = new Gauge("Volume:", true, 10, 1); fmMain.append(siVolume); fmMain.append(gVolume); gVolume.addCommand(cmSair); gVolume.setItemCommandListener(this); display.setCurrent(fmMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command arg0, Item i) { destroyApp(true); notifyDestroyed(); } }

Listagem 14: Exemplo de uso do Gauge interativo.

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ExGauge extends MIDlet implements ItemCommandListener, CommandListener, Runnable{ private Display display; private Form fmMain; private Gauge gVolume; private StringItem siVolume; private Command cmSair; private Command cmInicia; public void startApp() { display = Display.getDisplay(this); fmMain = new Form("Configuraes de volume"); cmSair = new Command("Sair", Command.EXIT, 1); cmInicia = new Command("Inicia", Command.ITEM, 1); siVolume = new StringItem("Configurar Volume", null); gVolume = new Gauge("Volume:", true, 10, 1); fmMain.append(siVolume); fmMain.append(gVolume); fmMain.addCommand(cmInicia); fmMain.setCommandListener(this); gVolume.addCommand(cmSair); gVolume.setItemCommandListener(this); display.setCurrent(fmMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command arg0, Item i) { destroyApp(true); notifyDestroyed(); } public void commandAction(Command arg0, Displayable arg1) {

Listagem 15: Exemplo de uso do Gauge com Thread.

Figura 40: Exemplo de Gauge no emulador da Sun. StringItem selecionado.

Figura 41: Exemplo de Gauge no emulador do aparelho Sanyo MM-5600.

10.7 Spacer A classe javax.microedition.lcdui.Spacer insere um espao entre Itens dentro de um Form. Seu construtor recebe apenas dois parmetros, a sua largura e altura mnima. A Figura 42 mostra um exemplo de utilizao do componente entre dois StringItems, a figura ao lado, apresenta a mesma classe, porm, sem o Spacer entre os dois itens. O Spacer est presente a partir da MIDP 2.0, no permite a insero de Commands e no aceita a utilizao de nmeros negativos para configurao de seu tamanho mnimo. A Listagem 16 apresenta o cdigo da classe exemplo utilizado nas Figuras 42 e 43.

Construtor da classe Spacer


Spacer(int larguraMinima, int alturaMinima) Cria um novo objeto Spacer com seu tamanho mnimo.

Principais mtodos da classe Spacer


void setMinimumSize(int larguraMinima, int alturaMinima)

Sets the minimum size for this spacer.

Figura 42: Exemplo de utilizao do Gauge no emulador do LG 325.

Figura 43: Classe de exemplo de Gauge, com a linha que adiciona o componente ao Form comentada.

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ExSpacer extends MIDlet { private Display display; private StringItem siNome, siSobrenome; private Spacer espaco; private Form fmMain; public void startApp() { display = Display.getDisplay(this); siNome = new StringItem("Nome: ", "Ricardo"); siSobrenome = new StringItem("Sobrenome: ", "da Silva Ogliari"); espaco = new Spacer(100, 20); fmMain = new Form("Ex. Spacer"); fmMain.append(siNome); //fmMain.append(espaco); fmMain.append(siSobrenome); display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } }

Listagem 16: Exemplo de uso da classe Spacer.

10.8 CustomItem A classe javax.microedition.lcdui.CustomItem permite que o programador crie seus prprios componentes. Subclasses gerados a partir desta classe tem controle sobre todos os elementos de interface do item, assim como sua interao com os usurios. Cada subclasse de CustomItem possui uma largura e altura mnima configurvel para a rea total e rea de contedo do componente. Sua rea de responsabilidade do programador implementar, sua borda e seu rtulo fica a cargo da implementao da MIDP presente no dispositivo mvel. Se a informao de tamanho mnimo passado e maior que o tamanho mximo permitido pela tela, a classe tem o domnio de atribuir um valor menor para este atributo. Ela est presente somente a partir da verso 2.0 do perfil MIDP.
10.8.1 Modos de Interao

A classe possui vrios modos de interao, fica a cargo da implementao da MIDP decidir quais deles sero configurados dentre de um dispositivo. Cada subclasse de CustomItem pode utilizar de Item Commands, eventos de teclado e eventos de toque na tela (no caso de telas touch-screen). A implementao no obrigada a implementar eventos de teclado nem de toques na tela. Alm disso, um dispositivo pode suportar evento KEY_PRESSED e KEY_RELEASED, porm, no oferecer suporte a eventos KEY_REPEATED. A mesma analogia serve para os eventos de POINTER_PRESSED, POINTER_RELEASE e POINTER_DRAG. Os modos de interao so aplicveis tambm classe Canvas, que discutida posteriormente neste texto.
10.8.2 Traversal

A classe CustomItem permite que a implementao da MIDP fornea uma maneira do programador definir o comportamento nos eventos de entrada e sada do componente. Com isso, possvel, por exemplo, implementar uma animao a cada vez que o usurio visita o item. possvel a implementao de TRAVERSE_HORIZONTAL e TRAVERSE_VERTICAL, porm, nenhum dos dois obrigatrio.
10.8.3 Aplicao Exemplo

Para que o aprendizado da classe CustomItem seja completo, vamos desenvolver uma nova API, o nome dela ser MReport. Esta API se prope a construtir relatrios na plataforma Java ME, de forma simples e

totalmente customizvel, podendo ser baseada na ferramenta iReport, altamente usada na plataforma Java SE. A pgina oficial do projeto est aqui: http://www.jasperforge.org/sf/projects/ireport. Outro ponto importante, no nossa idia implementar todas as funcionalidades que a ferramenta possui, porque os ambientes Desktop e Mobile apresentam vrias e severas diferenas na capacidade de armazenamento e processamento de dados.
import java.util.Vector; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ExCustomItem extends MIDlet { private Display display; private Relatorio relatorio; private StringItem titulo; private Form fmMain; private Font fonte; private Font fonte2; public void startApp() { display = Display.getDisplay(this); fmMain = new Form("Relatrio de Cidades"); titulo = new StringItem("Estado: ", "Rio Grande do Sul"); fmMain.append(titulo); relatorio = new Relatorio(fmMain.getWidth(), 150); ... ... configuraes da classe Relatrio.. ... ... fmMain.append(relatorio); display.setCurrent(fmMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} }

Listagem 17: Midlet que faz uso da classe CustomItem

A Listagem 17 apresenta o cdigo da classe MIDlet que faz uso do CustomItem. Perceba que ele tratado como qualquer outro Item da MIDP. Um objeto da classe Relatorio (classe que extende de CustomItem) criado, instanciado e depois anexado a instncia da classe Form, atravs do mtodo append(), at o presente momento o leitor no deve ter se surpreendido nem um pouco. Espere um pouco mais.

O grande diferencial entre os outros Itens e a CustomItem est na implementao do mtodo paint(). No CustomItem esta tarefa fica a cargo do programador, por isso um item customizvel. Os outros itens da MIDP j vem com este mtodo implementado e impossvel altera-los. A Listagem 18 mostra o cdigo da classe Relatrio. Quando uma classe extende diretamente de CustomItem, ela deve impementar, de forma obrigatria, os seguintes mtodos: getMinContentWidth(), getMinContentHeight(), getPrefContentWidth(int largura), getPrefContentHeight(int altura) , paint(Graphics arg0, int arg1, int arg2). Os mtodos getMinContentWidth() (linha 15) e getMinContentHeight() (linha 18) definem a largura e altura mnima do novo componente. Os mtodos getPrefContentWidth(int largura) e getPrefContentHeight(int altura), que esto nas linhas 21 e 24 respectivamente, definem a largura e altura preferencial do componente. Por fim, o mtodo paint define o contedo visual do componente personalizado. Os mtodos pointerPressed (linha 32), pointerDragged (linha 37) e pointerReleased (linha 39) servem para dar possibilidade de interao com a caneta do dispositivo. Por fim, os mtodo traverse (linha 42) e traverseOut (linha 48) possibilitam programar o comportamento quando o usurio entrar e sair do componente.

1: class Relatorio extends CustomItem 2: { 3: private int minContentWidth, minContentHeight, prefContentHeight, prefContentWidth; 4: outros objetos 5: 6: public Relatorio(int width, int height) 7: { 8: super(""); 9: 10: prefContentHeight = height; 11: prefContentWidth = width; 12: minContentHeight = height; 13: minContentWidth = width; 14: } 15 protected int getMinContentWidth() { 16: return minContentWidth; 17: } 18: protected int getMinContentHeight() { 19: return minContentHeight; 20: } 21: protected int getPrefContentWidth(int arg0) { 22: return prefContentWidth; 23: } 24: protected int getPrefContentHeight(int arg0) { 25: return prefContentHeight; 26: } 27: 28: protected void paint(Graphics g, int largura, int altura) { 29: ... desenho das diretivas grficas 30: } 31: 32: protected void pointerPressed(int x, int y) 33: { 34: cdigo de implementao do evento 35: } 36: 37: protected void pointerDragged(int x, int y) 38: {} 39: protected void pointerReleased(int x, int y) 40: {} 41: 42: protected boolean traverse(int dir, int viewportWidth, int viewportHeight, 43: int[] visRect_inout) 44: { 45: cdigo de implementao do evento 46: } 47: 48: protected void traverseOut() 49: { 50: cdigo de implementao do evento; 51: } 52: }

Listagem 18: Classe que herda diretamente de CustomItem.

protected void paint(Graphics g, int largura, int altura) { int aux = 0; g.setColor(255, 255, 255); g.fillRect(0, 0, largura, altura); if (titleFillColor) // se sim, o ttulo tem cor de fundo { g.setColor(titleColorBack[0], titleColorBack[1], titleColorBack[2]); g.fillRect(0, 0, largura, titleFont.getHeight() + 2); } g.setColor(titleColorText[0], titleColorText[1], titleColorText[2]); if (titleAlignment == LEFT) g.drawString(title, largura/2, 1, Graphics.LEFT|Graphics.TOP); else if (titleAlignment == CENTER) g.drawString(title, largura/2, 1, Graphics.HCENTER|Graphics.TOP); else g.drawString(title, largura/2, 1, Graphics.RIGHT|Graphics.TOP); if (titleBorder) //verifica se o ttulo tem borda { g.setColor(titleColorBorder[0], titleColorBorder[1], titleColorBorder[2]); g.drawRect(0, 0, largura, titleFont.getHeight() + 2); } aux = titleFont.getHeight() + 4; if (columnsFillColor)//se sim, as colunas tem background, seno, transparente { int auxW = 1; g.setColor(columnsColorBack[0], columnsColorBack[1], columnsColorBack[2]); for (int i = 0; i < columnsText.length; i++) { g.fillRect(auxW - 1, aux, columnsPercents[i]-1, columnsFont.getHeight() + 2); auxW += columnsPercents[i]; } }

Listagem 19: Mtodo paint da classe que herda diretamente de CustomItem

A Listagem 19 apresenta o mtodo paint() j codificado em um dos relatrios da MReport. Nesse momento o cdigo no ser explicado, isso porque, as classes Graphics e Canvas tero um tpico s pra elas. O importante a ser compreendido na Listagem 19 um quesito: o responsvel pelo desenho de toda a interface a classe que estende de CustomItem e implementa o mtodo paint, utilizando de diretivas grficas (linhas, retngulos, linhas etc) para formar a interface grfica do componente. A Figura 44 apresenta a API em execuo e o resultado das ltimas Listagens.

Construtor da classe CustomItem


protected CustomItem(String rotulo)

Construtor da superclasse, fornecendo uma maneira de suas subclasses especificarem seus rtulos.

Principais mtodos da classe CustomItem


int getGameAction(int codigoTecla)

Retorna o game action associado com o cdigo de tecla do dispositivo.


protected getInteractionModes() int Retorna os modos de interatividade disponveis. protected getMinContentHeight() abstract Implementado pela subclasse para retornar int de contedo do componente, em pixeis. protected getMinContentWidth() abstract Implementado pela subclasse para retornar int de contedo do componente, em pixeis. protected getPrefContentHeight(int width) abstract Implementado pela subclasse para retornar int de contedo do componente, em pixeis. protected getPrefContentWidth(int height) abstract Implementado pela subclasse para retornar int de contedo do componente, em pixeis. protected hideNotify() void Chamado

a altura mnima da rea

a largura mnima da rea

a altura preferida da rea

a largura preferida da rea

pelo sistema para notificar o item que ele est invisvel no momento, quando estava previamente visvel. tamanho do ustomItem's e a localizao de traversal necessitam ser atualizadas. uma tecla pressionada. uma tecla liberada. uma tecla repetida.

protected invalidate() void Sinaliza que o

protected keyPressed(int codigoTecla) void Chamado pelo sistema quando protected keyReleased(int codigoTecla) void Chamado pelo sistema quando protected keyRepeated(int codigoTecla) void Chamado pelo sistema quando

protected paint(Graphics g, int largura, int altura) abstract Implementado pela subclasse para renderizar o void container. protected pointerDragged(int x, int y) void Chamado pelo sistema, quando

item dentro de seu

uma ao de arrasto de ponteiro (canetas presentes em dispositivos touch-screen, como PDAs) ocorre dentro do item. um evento de pressionamento de

protected pointerPressed(int x, int y) void Chamado pelo sistema quando

pontiro ocorre dentro do item.


protected pointerReleased(int x, int y) void Chamado pelo sistema quando

o usurio tira o ponteiro do contato

com o dispositivo, dentro do item.


protected repaint() void Requisita que o

item seja repintado. x, y e com

protected repaint(int x, int y, int largura, int altura) void Solicita que o item seja repintado a partir de um ponto

uma largura e altura determinados.


protected showNotify() void Chamado

pelo sistema para notificar o item que ele est visvel. eventos de

protected sizeChanged(int largura, int altura) void Implementado pela subclasse para tartar dos

redimensionamento.
protected traverse(int dir, int viewportWidth, int viewportHeight, boolean int[] visRect_inout)

Chamado pelo sistema quando o sistema acessa o item, ou quando eventos de teclado so acionados dentro do item.
protected traverseOut() void Chamado pelo

sistema quando o sistema sai do item.

Figura 44: Exemplo de Canvas sem fullscreen.

11. Interface grfica de baixo nvel - Canvas


Como vimos anteriormente, o Java ME nos fornece alguns componentes prontos para uso, tornando a curva de aprendizado e desenvolvimento mais rpida. Porm, esses mesmos componentes no apresentam um comportamento de interface uniforme nas diversas plataformas mbile existentes no mercado, tambm, alguns opes de configuraes so impossveis, como uma cor de fundo em um componente Form e seus itens. Sendo assim, importante conhecer a forma de construo de interface em baixo nvel, com as classes Canvas e Graphics, ambas do pacote javax.microedition.lcdui. importante ressaltas que uma tela construda com Canvas no pode conter qualquer outro elemento visto anteriormente, ou seja, o desenvolvedor tem que optar por ela ou por uma das instncia da classe Screen. 11.1 Canvas A classe Canvas permite que programadores construam suas interfaces grficas em baixo nvel, ou seja, todo o controle de eventos, e desenho na tela, so sua responsabilidade. O ponto chave o mtodo paint(), na Canvas este mtodo abstrato, sendo responsabilidade do desenvolveor implementar o mtodo, fornecendo chamadas para diretivas grficas, desenhando linhas, arcos, crculos, configurando cores e traados, at atingir a interface grfica desejada. Nos componentes vistos anteriormente, como o DateField e o TextFeld por exemplo, o mesmo mtodo paint() j est implemetado, por isso seu uso torna-se mais fcil, porm sua interface mais fechada e no possvel alteraes. Lembrando sempre, que para uma aplicao, possvl conciliar tanto telas criadas com filhos da classe Screen, como Canvas, podendo alternar entre elas. Um bom exemplo a configurao de um jogo, dados como volume, nome do jogador e nvel de dificuldade podem ser construdos com a classe Form e seus itens. J a tela do jogo em si, seria desenhada com Canvas. Alm de precisar construir a interface da tela, o programador precisa tratar diretamente com os eventos de teclado. Na MIDP, existem oito mtodos que tem essa finalidade:

showNotify() hideNotify() keyPressed() keyRepeated() keyReleased() pointerPressed() pointerDragged() pointerReleased()

O primeiro mtodo chamado antes do Canvas se tornar visvel para o usurio da aplicao. J o hideNotify chamado aps o Canvas ser removido da tela, substitudo por outro Canvas, um Screen, ou ainda, alguma tela do prprio sistema operacional do dispositivo. Os ltimos seis mtodos da lista s podem ser chamados no intervalo dos dois primeiros mtodos, ou seja, enquanto a instncia de Canvas estiver visvel para o usurio da aplicao. Os mtodos keyPressed, keyRepeated e keyReleased so referents a evento do teclado do aparelho, que geralmente obedece ao padro ITU-U, presente na grande maioria dos telefones celulares. Os mtodos pointerPressed, poiterDragged e pointerReleased tratam de eventos de ponteiros, como as canetinhas que so usados em equipamentos como o PDA. Os eventos de ponteiros no so implementados de forma obrigatrio, isso porque, nem todos dispositivos mveis tem tela sensvel ao toque. Nos eventos de teclado, apenas o keyRepeated pode no estar implementado. Para verificar sua presena ou no, pode-se usar o mtodo hasRepeatedEvents() que retorna um valor booleano, true para suporte e false para a ausncia dele. O tratamento de eventos ser visto completamente posteriormente. 11.2 Modos de Operao Uma tela construda com Canvas, pode estar opervel em dois modos, full screen mode ou modo padro. Para configurar a instncia como full screen, utiliza-se o mtodo setFullScreenMode(boolean modo). Lembrando que este mtodo est presente somente a partir da verso 2.0 da MIDP. A Figura 45 apresenta uma tela Canvas sem o uso de full screen. Perceba que a visualizao do Ticker adicionado ao Canvas, bem como seus Commands, possvel. Na Figura 46 o Canvas seta com o full screen habilitado, perceba que tanto o Ticker, quando os Commands no se tornam mais visveis. Apesar disso, a implementao deixa os comandos ativos, por exemplo, se voc chamar a key que abriria o menu da esquerda ou da

direita, ele ir abrir da mesma forma, tornando-se visvel a partir deste momento.

Figura 45: Exemplo de Canvas sem fullscreen.

Figura 46: Exemplo de Canvas com fullscreen.

Um fato curioso sobre os modos de operao acontece no aparelho W380 da Sony Ericsson. O comportamento padro definido pela documentao oficial da Canvas, diz que, quando um Canvas opera no modo full screen, os Tickers associados a esta tela tornam-se invisveis, porm, veja na Figura 47 o comportamento no referido telefone celular. Perceba que o Ticker continua visvel na parte superior do aplicativo. A imagem tambm til para perceber a falta de padronizao entre o resultado obtido no emulador da Sun Microsystems (Figura 45) e no ambiente real de execuo.

Figura 47: Exemplo de Canvas com fullscreen executando em um aparelho Sony Ericsson W380.

11.3 Graphics Como dito anteriormente, a responsabilidade de construo das interfaces construdas em baixo nvel do programador. Isso feito com a classe Canvas e a javax.microedition.lcdui.Graphics. Esta ltima permite a renderizao de simples formas geomtricas 2D. Atravs de mtodos que permitem a construo de desenhos primitivos, como linhas, retngulos, arcos, textos e imagens. O modelo de cores utilizado o de 24 bits, onde so separados 8 bits para cada componente da cor: 8 bits para vermelho, 8 bits para verde e 8 bits para azul. Hoje em dia, a grande maioria dos aparelhos que suportam a MIDP, seno a totalidade, tem suporte a este esquema de cores. Porm, no comeo da programao Java ME ainda existiam as telas monocromticas, sendo assim, a MIDP consegue trabalhar com este esquema de cores mesmo em aparelhos que no a suportem, transpondo as cores para uma escala de cinza. A classe Display fornece o mtodo isColor(), que retorna um valor booleano true se o dispositivo suporta cores e false se no h. Na questo das cores, existe ainda um fato importante, dependendo de questes de implementao e suporte grfico do dispositivo, a cor que voc especifica pode sofrer algumas distores no display do aparelho, para isso,

existe o mtodo getDisplayColor(int color) que recebe uma cor e retorna a cor que ser impressa no display do aparelho pela implementao da MIDP. O esquema usada pelo Graphics para desenho das diretivas grficas o Source Over Destination, onde os pixeis de origem sobrepe os pixeis de destino. Para o desenho de linhas, arcos, textos e retngulos a regra utilizar apenas pixeis opacos, porm, para desenho de imagens, possvel o uso de transparncia e semi-transparncia. Neste contexto, se o pixel transparente, o pixel de destino no sofre modificao, se o pixel fonte semi-transparente a MIDP utiliza processo Alpha blending. Porm, a implementao da MIDP pode suportar somente pixeis opacos tambm nas imagens, sendo assim, os pixeis transparentes e semi-transparentes da imagem so removidos no momento de sua construo. O sistema de coordendas basea-se no canto superior esquerdo, que representa o ponto (0, 0). O eixo X cresce para a direita e o eixo Y para baixo. Veja a Figura 48.

Figura 48: Sistema de coordenadas da Graphics.

A seguir, duas tabelas so apresentadas, mostrandos as constantes da classe e alguns dos seus mtodos:

Constantes da classe Graphics


Static int BASELINE

Constante que posiciona o ponto de ncora na base do texto.


static int BOTTOM

Constante para posicionar o ponto de ncora de textos e imagens

abaixo dos mesmos.


static int DOTTED

Constante para o estilo da linha DOTTED.


static int HCENTER

Constante para centrar textos e imagens horizontalmente em torno do ponto de ncora.


static int LEFT

Constante para posicionar o ponto de ncora na esquerda de textos e imagens.


static int RIGHT

Constante para posicionar o ponto de ncora na direita de textos e imagens.


static int SOLID

Constante para o estilo de linha SOLID.


static int TOP

Constante para posicionar o ponto de ncora acima de textos e imagens.


static int VCENTER

Constante para centrar imagens verticalmente em torno do ponto de ncora.

Mtodos da classe Graphics


Void clipRect(int x, int y, int largura, int altura)

Intersecta o clip corrente com o retngulo especificado.


Void copyArea(int x_src, int y_src, int largura, int altura, int x_dest, int y_dest, int ancora) Copia o contedo de uma rea retangular (x_src, y_src, largura, altura) para uma area de destino, identificado pela posio (x_dest, y_dest) e ponto de ncora (int ancora). Void drawArc(int x, int y, int largura, int altura, int inicioAngulo, int arcoAngulo)

Desenha um arco vazio circular ou elptico, usando a cor e estilo de linha corrente.
Void drawChar(char caracter, int x, int y, int ancora)

Desenha um character usando a fonte e cor atual.


Void drawChars(char[] data, int comeco, int tamanho, int x, int y, int ancora)

Desenha os caracteres de um vetor usando a fonte e cor corrente.


Void drawImage(Image img, int x, int y, int ancora)

Desenha uma imagem usando um ponto de ncora.


Void drawLine(int x1, int y1, int x2, int y2) Desenha uma linha entre duas coordenadas (x1,y1)

e (x2,y2) usando a

cor e estilo de linha atual.


Void drawRect(int x, int y, int largura, int altura)

Desenha um retngulo vazio usando a cor e estilo de linha corrente.

Void drawRegion(Image fonte, int x_src, int y_src, int largura, int altura, int transformacao, int x_dest, int y_dest, int ancora)

Copia a regio de uma imagem para um local dentro do destino, possibilidade de transformao na imagem fonte usando a funo de transformao adequada.
Void drawRoundRect(int x, int y, int largura, int altura, int arcoLargura, int arcoAltura)

Desenha um retngulo vazio com cantos arredondados usando a cor e estilo de alinha correntes.
Void drawString(String fonte, int x, int y, int ancora) Desenha um String usando a fonte e cor corrente. Void drawSubstring(String fonte, int inicio, int tamanho, int x, int y, int ancora) Desenha uma substring de uma String usando a cor e fonte corrente. Void fillArc(int x, int y, int largura, int altura, int inicioAngulo, int arcoAngulo)

Desenha um arco circular ou elptico preenchido utilizando a cor corrente.


Void fillRect(int x, int y, int largura, int altura)

Desenha um retngulo preenchido com a cor e estilo de linha atuais.


Void fillRoundRect(int x, int y, int largura, int altura, int arcoLargura, int arcoAltura)

Desenha um retngulo arredondado e preenchido, utilizando a cor e estilo de linha atuais.


Void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3)

Desenha um tringulo preenchido utilizando a cor atual.


Int getBlueComponent()

Retorna o componente azul da cor atual.


Int getColor()

Retorna a cor atual.


int getDisplayColor(int color)

Retorna a cor que sera mostrada no display se color for requisitada.


Font getFont()

Retorna a fonte atual.


int getGreenComponent()

Retorna o componente verde da cor atual.


int getRedComponent()

Retorna o componente vermelho da cor atual.


void setClip(int x, int y, int largura, int altura)

Configura o clip corrente para o retngulo especificado com as coordenadas passadas por parmetro.
void setColor(int RGB)

Configura a cor atual.


void setColor(int red, int green, int blue)

Configura a cor atual.


void setFont(Font font)

Configura a fonte a ser usada em todas as operaes de escrita seguintes.


void setStrokeStyle(int estilo)

Configura o estilo de linha que sera usado para as prximas operaes com linhas, retngulos, retngulos arredondados e arcos.
void translate(int x, int y)

Translada a origem do contexto grfico para o ponto (x, y) no sistema de coordenadas atual.

11.4 Estilo de Linha Na API da classe Graphics, construmos a interface atravs de desenhos primitivos, estes, so compostos basicamente por linhas, como no retngulo por exemplo. Esta linha pode ter duas aparncias, linha cheia (SOLID) ou pontilhada (DOTTED). Para configurar o estilo de linha utiliza-se o mtodo setStrokeStyle(), passando como parmetro uma das duas constantes da classe: DOTTED ou SOLID. Lembrando que aps a chamada do mtodo, todas as operaes de desenho de retngulos, arcos e linhas faro uso deste estilo. A Figura 49 apresenta um retngulo desenhado com estilo de linha DOTTED e, um crculoq eu faz uso do estilo SOLID. O espaamento estreos pontilhados no estilo DOTTED depende da implementao da MIDP.

Figura 49: Exemplo de estilos de linha na classe Graphics.

12. Interface grfica de baixo nvel Programando


Como dito no captulo anterior, a programao de interface de usurio em baixo nvel feita com a classe Canvas e chamadas a diretivas grficas na classe Graphics. O primeiro passo construir uma classe que extenda da classe Canvas e, de forma obrigatrio, implement o mtodo paint(Graphics). A Listagem 20 apresenta o uso primrio da classe Canvas.
1: import javax.microedition.midlet.MIDlet; 2: import javax.microedition.lcdui.*; 3: 4: public class ExCanvas extends MIDlet 5: { 6: private Tela tela; 7: private Display display; 8: 9: public void startApp() 10: { 11: display = Display.getDisplay(this); 12: 13: tela = new Tela(); 14: 15: display.setCurrent(tela); 16: } 17: 18: public void pauseApp() 19: {} 20: public void destroyApp(boolean teste) 21; {} 22:} 23: 24: 25: class Tela extends Canvas 26: { 27: protected void paint(Graphics g) 28: { 29: } 30: }

Listagem 20: Uso primrio da classe Canvas

As duas primeiras linhas so os imports necessrios. A seguir, declaramos a classe e, na linha 6, criamos um objeto da classe Tela, que extende de Canvas. Seu uso semelhante aos componentes vistos anteriormente, ou seja, depois de instanciada (linha 13) basta passar como parmetro ao mtodo setCurrent da classe Display (linha 15).

A classe Tela tem incio na linha 25. O esqueleto bsico para utilizao de interface em baixo nvel e mostrado de forma total em seis linhas. Ou seja, basta fazer o extends para Canvas e implementar o mtodo paint(), linha 27. O resultado desta Listagem pode ser visto na Figura 50.

Figura 50: Uso primitivo da Canvas.

O leitor deve estar se perguntando oque aconteceu, j que a tela continua igual. Isso acontece porque at a tarefa de limpeza da tela tarefa do programador. Perceba que o emulador da Sun apresenta uma opo Launch antes de iniciar o aplicativo e, na Figura 50, essa opo no existe. Isso porque o aplicativo j est sendo executado, porm, no foi feito nenhuma chamada s diretivas grficas no mtodo paint da classe Tela. 12.1 Desenhando retngulos O retngulo criado pode ser de trs formas: vazio, preenchido e, as duas opes anteriores com cantos arredondados. Os mtodos necessrios so: drawRect, fillRect, drawRoundRect e fillRoundRect. Cabe ressaltar nesse momento que todas as alteraes feitas na ltima listagem sero feitas no mtodo paint. Os dois primeiros mtodos tem a mesma assinatura:

int x, int y, in largura, int altura

Os dois primeiros parmetros identificam a posio dentro do sistemas de coordendas do retngulo, j os parmetros de largura e altura definem as dimenses da regio afetada pelo retngulo. Ainda lembram da limpeza a ser feita no inerface? Ela pode ser feita com o fillRect. Lembre-se que tanto o fillRect quanto o drawRect tem a mesma assinatura de mtodo, oque difere osdois mtodo, que fill identifica um retngulo preenchido, ou seja, a cor que est sendo utilizada no momento da chamada do mtodo utilzada para preencher o retngulo. Na Listagem 21 alteramos sensivelmente o cdigo. A linha 3 define a cor a ser utilizada como um tom de cinza claro (utilizamos o cdigo RGB, quando os trs valores so iguais sempre obtm-se como resultado um tom de cinza, quanto maiores os valores dos componentes mais claro ser este tom). Na linha 4 desenhamos um retngulo preenchido que est localizado no ponto (0, 0), ou seja, no canto superior esquerdo da tela e tem como largura e altura os valores de largura e altura do prprio display, para saber isso utlizamos os mtodos getWidth (para largura) e getHeight (para altura). O resultado dessa Listagem est sendo mostrado na Figura 51, perceb que agora sim percebe-se claramente que o aplicativo est sendo executado, devido ao pano de fundo cinza (resultado da linha 4). Continuando na Listagem, a linha 6 altera novamente a cor a ser utilzada para azul, e, em seguida, na linha 7, desenha um retngulo vazio na posio (40, 40), com largura igual a 100 e 50 de altura. Lembrando que os valores de largura e altura so dados em pixeis. Para firmar o conceito de estilo de linha utlizamos um retngulo pontilhado na linha 10, depois de ter configurado o estilo na linha 9.
1: protected void paint(Graphics g) 2: { 3: g.setColor(199, 199, 199); 4: g.fillRect(0, 0, getWidth(), getHeight()); 5: 6: g.setColor(0, 0, 255); 7: g.drawRect(40, 40, 100, 50); 8: 9: g.setStrokeStyle(Graphics.DOTTED); 10: g.drawRect(120, 120, 50, 50); 11: }

Listagem 21: Utilizao de retngulos

Perceba que a Figura 52 apresenta o resultado do mesmo cdigo, porm, ela est no modo full screen. Isso foi obtido sobrescrevendo o

construtor da classe Tela, e adicionando uma chamada ao mtodo setFullScreemMode(), passando true como parmetro. Por padro o valor false. Veja a Listagem 22.
class Tela extends Canvas { public Tela() { setFullScreenMode(true); } protected void paint(Graphics g) { } }

Listagem 22: Configurando full screen mode no Canvas.

Figura 51: Uso de retngulos na Canvas.

Figura 52: Uso de retngulos na Canvas em uma tela full screen mode.

12.2 Desenhando linhas Para desenhar uma linha no Canvas utliza-se o mtodo drawLine(int x1, y1, x2, y2). Os quatro parmetros passados ao mtodos representam o ponto inicial e final no sistema de coordenadas do dispositivo, a API trata de criar a linha entre os dois pontos. Vamos alterar o cdigo da listagem anterior para adicionar duas linhas na tela, retirando os dois quadrados. Veja o cdigo na Listagem 23 e o resultado grfico na Figura 53. Nesse momento introduzimos uma boa dica de programao. inadequado usar os mtodos getWidth() e getHeight() a cada vez que precisarmos saber a largura e altura total do display, o mais indicado criar duas variveis que armazenam estes valores, no exemplo da Listagem 23 as variveis so largura e altura, configuradas nas linhas 10 e 11 respectivamente. O quadrado de limpeza de tela continua (linha 17), a seguir, configuramos a cor para azul (linha 20) e criamos a primeira linha (linha 21), que vai da localizao (10, 10) at a localizao (100, 100). A linha 22 altera o estilo usado para DOTTED, a linha seguinte altera a cor para totalmente preto. A linha 24 desenha uma linha que se situa exatamente no centor da tela no sentido vertical. Perceba que utilizamos (altura / 2) e no um valor fixo, porque isso? Porque se colocarmos um valor fixo podemos achar o centro da tela on celular apresentado pelo emulador da Sun, porm, em outras plataformas o valor do centro da tela ir variar, causando um erro terrvel no aplicativo. Sendo assim, a altura total do display dividido por dois sempre retornar o centro da tela no sentido vertical, independente de plataforma e/ou dispositivo.
1: class Tela extends Canvas 2: { 3: private int largura; 4: private int altura; 5: 6: public Tela() 7: { 8: setFullScreenMode(true); 9: 10: largura = getWidth(); 11: altura = getHeight(); 12: } 13: 14: protected void paint(Graphics g) 15: { 16: g.setColor(199, 199, 199); 17: g.fillRect(0, 0, getWidth(), getHeight()); 18: 19; g.setColor(0, 0, 255); 20: g.drawLine(10, 10, 100, 100); 21; 22: g.setStrokeStyle(Graphics.DOTTED); 23: g.setColor(0, 0, 0); 24: g.drawLine(10, altura/2, largura - 20, altura/2); 25: } 26: }

Listagem 23: Desenho de linhas no Canvas

Figura 53: Uso de linhas no Canvas.

12.3 Desenhando arcos Quer desenhar um crculo, utilize arcos em Java ME MIDP, achou estranho? Pois vou mostrar a seguir o porque dessa afirmao. De forma similar aos retngulos, para desenhar arcos temos duas possibilidades, preenchidos ou vazios, fillArc e drawArc so usados, respectivamente. Ambos recebem o mesmo conjutno de parmetros, que podem ser vistos a seguir:
(int x, int y, int arcoAngulo) int largura, int altura, int inicioAngulo,

Os dois primeiros parmetros definem a posio do arco no sistema de coordenadas, a largura e altura definem sua dimenso. InicioAngulo define o ponto inicial do arco, visto que, um arco completo tem 360 graus, formando um crculo. ArcoAngulo define o ngulo que o arco ter.

Para fixar estes conceitos, vamos desenhar um crculo aberto e fechado e, em seguida, criaremos um desenho do Pac Man, famoso personagem de um antigo jogo de vdeo-game. Veja a Listagem 24 com o novo cdigo inserido no mtodo paint() e, a Figura 54 para verificar o resultado grfico.
1: g.fillArc(0, 0, 50, 50, 60, 360); 2: g.drawArc(largura-50, 0, 50, 50, 0, 360); 3: g.fillArc(80, 80, 60, 60, 50, 270);

Listagem 24: Desenho de arcos no Canvas

Perceba que apenas adicionamos algumas linhas, na primeira criamos um arco prenchido no canto superior direito do display, a seguir, colocamos um arco vazio na lado oposto, note o uso do largura - 50 para referenciar a posio X do arco. O motivo o mesmo explicado anteriormente, ou seja, que a posio fique portvel para qualquer sistema de coordenadas em qualquer plataforma e/ou dispositivo. Nas duas primeiras linha o parmetro arcoAngulo est como 360, ou seja, o arco fechado completamente gerando um crculo. Sendo assim, o parmetro inicioAngulo irrelevante. J na ltima linha, que gera o nosso Pac-Man, o arcoAngulo est como 270, ou seja, sobram 90 graus para o crculo fechar. Perceberam agora porque da pergunta no incio deste tpico?

Figura 54: Uso de arcos no Canvas.

12.4 Ponto de ncora Antes de explicarmos o desenho de textos e imagem na Canvas preciso dissertar um pouco sobre o ponto de ncora. Ponto de ncora um conjunto de dois valores inteiros, definidos por constantes na prpria classe Graphics. Este ponto define o incio do processo de renderizar o texto ou a imagem. No total, a classe Graphics oferece nove constantes para este fim. Para explicar melhor este conceito, vamos mostrar alguns exemplos. O mtodo g.drawString recebe quatro parmetros: uma String do texto a ser desenhado, dois valores inteiros que definem a posio dentro do sistema de coordenadas e, por fim, o valor do ponto de ncora. Veja a Listagem 25, que apresenta o cdigo necessrio para escrever a frase Exemplo de ponto de ncora no display do dispositivo. Repare que todo o cdigo do mtodo paint foi removido, substitudo pelas linhas abaixo.
1: g.setColor(199, 199, 199); 2: g.fillRect(0, 0, getWidth(), getHeight()); 3: g.setColor(0, 0, 0); 4: g.drawString("Exemplo de ponto de ncora", 0, 0, Graphics.RIGHT|Graphics.TOP);

Listagem 25: Desenho de linhas no Canvas

Agora responda depressa, onde o leitor acha que este texto vai aparecer? No canto superior esquerdo. Se voc falou isso errou. Como dito anteriormente, o ponto de ncora, define a direo do processo de desenho dos caracteres que formam a String. No exemplo da listagem acima definimos os valores RIGHT (no sentido horizontal) e TOP (no sentido vertical), como seu ponto de localizao est (0, 0) o texto no aparece na tela. Porque a direo do texto est para a direita, sendo assim, ele fica a esquerda do ponto (0, 0) do dispositivo, onde o usurio no consegue visualizar. Veja na Figura 55 uma representao figurativo do que falei neste pargrafo. Agora imaginem que a gente mudou a linha 4 da Listagem 25, colocando Graphics.LEFT no lugar de Graphics.LEFT. Oque voc acha que vai acontecer? Com nossa mudana, a String passa a ser desenhada da esquerda para a direita, ou seja, ela ir aparecer no canto superior direito. Veja o resultado na Figura 56.

Figura 55: Ponto de ncora RIGHT usado de forma inadequada.

Figura 56: Ponto de ncora LEFT usado de forma adequada.

A mesma idia serve para o ponto de ncora no sentido vertical. No nosso exemplo estamos usando a constante TOP, com isso, a String desenhada de cima para baixo, como definido a posio (0, 0) como localizao no sistema de coordenadas, ele se adapta perfeitamente. Porm, se a linha 4 fosse alterada para:
g.drawString("Exemplo de ponto de ncora", 0, 0, Graphics.LEFT|Graphics.BOTTOM);

Teramos o resultado mostrado na Figura 57. A String aparece acima da parte visvel do usurio porque configuramos a localizao do texto como (0, 0), como a direo do texto comea de baixo para cima (BOTTOM), ele vai ocupar a posio (0, 0) at (0, -15) aproximadamente.

Figura 57: Ponto de ncora LEFT usado de forma adequada.

12.5 Desenhando Textos Para desenho de textos no Canvas, a classe Graphics oferece quatro mtodos: drawChar, drawChars, drawString e drawSubstring. O mtodo drawString j foi explicado anteriomente nas listagens que ajudaram a explicar o ponto de ncora. Adicionalmente, podemos falar que este mtodo no afetado pelo estilo de linha escolhido pelo usurio, somente pela cor corrente. O mtodo drawChar altera somente o primeiro parmetro, recebendo um char no lugar de uma String. DrawChars recebe como primeiro parmetro um vetor de caracteres, o segundo parmetro o ndice de incio do vetor e o terceiro parmetro define quantos caracteres sero desenhados na tela. Por fim, o mtodo drawSubstring desenha uma parte de um objeto String, o segundo e terceiro parmetro do mtodo tem a mesma funo que os usados no mtodo drawChars(). 12.6 Desenhando Imagens Para desenhar imagens, tambm teremos o conceito de ponto de ncora, visto anteriormente. O mtodo usado o drawImage(Image img, int x, int y, int ancora). O primeiro parmetro uma instncia daclasse Image, os dois parmetros inteiros servem para situar a imagem no sistema de coordenadas do aparelho, por fim, o ltimo inteiro define o ponto de ncora. Veja a listagem 26 e o resultado na Figura 58.

1: g.setColor(199, 199, 199); 2: g.fillRect(0, 0, getWidth(), getHeight()); 3: g.setColor(0, 0, 0); 4: g.drawImage(imgPergunta, largura >> 1, altura >> 1, Graphics.HCENTER|Graphics.VCENTER);

Listagem 26: Desenho uma imagem no Canvas

Figura 58: Desenho de imagem em Canvas.

Alguns pontos da listagem de cdigo devem ser levadas em considerao. Mais especificamente devemos olhar atentamente a linha 4 da Listagem 26. Primeiramente, para definir o ponto de localizao da imagem utilizamos (largura >> 1) e (altura >> 1), porque? O deslocamento de bits foi usado porque otimiza o processamento, ou seja, troque o uso de (largura/2) pelo deslocamento de bits, o resultado do clculo o mesmo com maior velocidade da mquina virtual Java. Vamos explicar rapidamente o conceito por trs do deslocamento de bits. Digamos que a largura da tela horizontalmente seja 240, seu valor em cdigo binrio :

1 2 4 8 16 32 64 128 256 0000 1 1 1 1 = 240

Agora vamos supor que aplicamos 4 vezes seguidas o deslocamento de bits a esquerda. Veja o resultado:
1 2 4 8 16 32 64 128 256 0000 1 1 1 0001 1 1 1 0011 1 1 0 0111 1 0 0 1111 0 0 0 1 = 240 0 = 120 0 = 60 0 = 30 0 = 15

Outro ponto na linha 4 que deve ser notado o uso do VCENTER na formao do ponto de ncora, este valor s pode ser usado com imagens. Quanto ao formato da imagem, aconselha-se utilizar o formato PNG8, que implementado de forma obrigatrio em todo dispositivo que tenha o perfil MIDP. O leitor pode utilizar PNG-16, JPG ou GIF, mas talvez seu aplicativo tenha problemas com portabilidade futuramente.

13. Interface grfica de baixo nvel - Interao com o usurio


A interao com usurio em equipamentos que possuem Java ME perfil MIDP pode acontecer de duas formas: por aes no teclado, como por exemplo acionar o SOFT_KEY esquerdo do aparelho ou, atravs de ponteiros, um exemplo perfeito disso so os aparelhos PDAs, que tem uma caneta. Vamos tratar dos dois modos de forma separada aqui. 13.1 Interao com eventos de teclado A API traz trs mtodos para esta funo:
keyPressed() keyRepeated() keyReleased()

Destes, apenas o keyRepeated no obrigatrio nas implementaes da MIDP. Para capturar eventos desses trs mtodos basta colocar sua implementao na classe, veja a Listagem 27, com os trs mtodos referidos anteriormente inseridos na classe Tela:
1: public void keyPressed(int keyCode) 2:{ } 3: 4: public void keyRepeated(int keyCode) 5:{ } 6: 7: public void keyReleased(int keyCode) 8:{ }

Listagem 27: Desenho uma imagem no Canvas

Antes de mais nada necessrio decifrar oque este keyCode que passado como parmetro para os trs mtodos acima. Todos os telefones celulares e smartphones (ou pelo menos a grande maioria) segue o padro

de teclas ITU-T, que define um teclado 3x4 contendo os nmeros de 1 at 9, alm do * e do #. Abaixo, segue uma figura ilustrando o padro mundial.

Figura 59: Exemplo de teclado no formato ITU-T.

A classe Canvas fornece constantes que definem os cdigos de teclas do formato padro, definidos pela ITU-T, sendo eles: KEY_NUM0, KEY_NUM1, KEY_NUM2, KEY_NUM3, KEY_NUM4, KEY_NUM5, KEY_NUM6, KEY_NUM7, KEY_NUM8, KEY_NUM9, KEY_STAR e KEY_POUND. Alm Disso, as teclas referentes ao padro tem seu cdigo igual ao seu sinnimo no Unicode. Por exemplo, o Unicode que define o nmero 5 53, dito isso, se, ao receber um evento keyPressed gerado pela tecla 5, imprimssemos o seu keyCode recebido como parmetro na tela, veramos 53. A mesma analogia serve para todos as teclas do padro ITUU. Porm, esta no a forma mais indicada de construir um aplicativo portvel, ou ainda, um jogo, que necessita de aes especficas de sua matureza. Para isso, a MIDP definiu oque chamado de game action, ou seja, aes comuns usadas na grande maioria dos jogos, sendo elas: UP, DOWN, LEFT, RIGHT, FIRE, GAME_A, GAME_B, GAME_C e GAME_D. Uma key code pode ser associada a no mximo uma game action, o contrrio no verdadeiro, sendo que uma game action pode ter vrias key code associadas. Tomamos como exemplo o aparelho celular da Figura 60. Para a ao de UP do jogo existem duas teclas que podem ser acionadas: o 2 e a seta direcional para cima. Sendo assim, a game action UP possui duas key code, porm, a key code do nmero 2 por exemplo, pertence somente a game action UP. Para recuperar a game action de uma key code, chame o mtodo getGameAction(keyCode).

Figura 60: Aparelho celular Nokia N-95 8GB.

13.1 Interao com eventos de ponteiro Alm dos eventos tradicionais de teclado, a MIDP e a classe Canvas permitem que o desenvolvedor possa tratar os eventos de ponteiro. O maior exemplo desse tipo de evento so os aparelhos do tipo PDA (Personal Digital Assistant). Neste tipo de equipamento, bem como, alguns aparelhos celulares, a tecla tem um recurso chamado touch screen, onde o usurio pode efetuar aes com toques no display do aparelho. Para recuperar e tratar destes eventos, a classe Canvas permite a implementao de quatro mtodos: pointerPressed, pointerReleased e pointerDragged. Os trs mtodos apresentam a mesma assinatura, recebendo dois valores inteiros como parmetros, definindo a posio x,y dentro do sistema de coordenadas do aparelhos onde a ao de touch screen foi definida. O primeiro mtodo chamado quando o ponteiro toca o display, o segundo quando o ponteiro perde contato com o display e, por fim, o terceiro, chamado quando o ponteiro se move sobre a rea do display. Veja a Listagem 28 com a implementao dos trs mtodos referidos anteriormente.

1: public void pointerPressed(int x, int y) 2:{ } 3: 4: public void pointerReleased(int x, int y) 5: { } 6: 7: public void pointerDragged(int x, int y) 8:{}

Listagem 28: Mtodos para captura de eventos de ponteiro.

Para emular este eventos na ferramenta Sun Wireless Toolkit, uma das mais conhecidas e utilizadas para programao de aplicativos Java ME, necessrio alterar um arquivo de configurao do software. At a verso 2.5.2 da Sun Java Wireless Toolkit for CLDC, deve-se abrir o arquivo de configurao que est na pasta Instalao/wtklib/devices/<emulador usado>/emuladorusado. Por exemplo, se for utilizado o emulador DefaultColorPhone, o arquivo Instalao/wtklib/devices/DefaultColorPhone/DefaultColorPhone deve ser editado. No momento da escrita desse livro, a Sun tinha acabado de lanar o software Java Platform Micro Edition Software Development Kit 3.0 Early Access. Nesta ferramenta, deve-se editar o arquivo <emulador usado>.properties encontrado em instalao/toolkitlib/devices/<emulador usado>/conf. Nos dois arquivos relatados anteriormente, deve-se alterar a propriedade:
touch_screen=false

Para:
touch_screen=true

14. Armazenamento de dados


Antes de comear a estudar a forma de persistncia de dados no Java ME, esquea tudo que j aprendeu sobre banco de dados relacionais, SGBDs tradicionais como Postgresql, Interbase, Firebird, dentre outros, so pssimas referncias, a no ser pela sua finalidade. No Java ME, mais especificamente no seu perfil MIDP, que estamos trabalhando aqui, a persistncia feita atravs de um banco de dados orientado a registros, chamado Record Management System (RMS). O RMS armazena e permite a recuperao de registros, chamados de Record Stores. Veja a 61, que traz uma representao visual do funcionamento do RSM e sua ligao com as MIDlets.

Figura 61: RMS e sua ligao com MIDlets.

Cada MIDlet pode acessar os da MIDlet Suite da qual faz parte. de responsabilidade do programador gerenciar de forma eficaz o mltiplo acesso de uma MIDlet aos dados oriundos de um Record Store. A plataforma de software do aparelho celular responsvel por implementar de forma eficaz o RMS, oferecendo uma maneira segura de persistir informaes. Alm disso, os cdigos de operaes em um RMS so traduzidos para cdigo gerenciados pelo prprio Sistema Operacional do aparelho, que mexe diretamente no seu mecanismo de persistncia de objetos. Por fim, responsabilidade do dispositivos manter os dados

intactos e corretos aps operaes do seu hardware e software, como reboot e falta de bateria. Um Record Store armazena somente um inteiro que trabalha como seu identificador nico e um vetor de bytes. Ele ainda possui um nome, que definido na sua criao. A Figura 62 apresenta um Record Store com uma srie de registros.

Figura 62: Record Store.

A partir de agora, veremos a codificao das operaes em um Record Store. Veja a tabela abaixo, ela traz todos os mtodos da classe javax.microedition.rms.RecordStore, na sequncia vamos vendo seus principais mtodos conforme a operao tratada.

Mtodos da classe RecordStore


int addRecord(byte[] dados, int offset, int numBytes)

Adiciona um novo registro para o record store.


void addRecordListener(RecordListener listener)

Adiciona um RecordListener ao record store.


void closeRecordStore()

Este mtodo chamado quando a MIDlet quer fechar o record store.


void deleteRecord(int recordId)

O registro apagado do record store.


static void deleteRecordStore(String recordStoreNome)

Deleta o record store nomeado.


RecordEnumeration enumerateRecords(RecordFilter filtro,

RecordComparator comparador, boolean manterEnumeracao)

Retorna uma enumerao de um conjunto de registros emu ma ordem especificada opcionalemente.


long getLastModified()

Retorna a data e hora da ltima atualizao no record store, no format System.currentTimeMillis().


String getName()

Retorna o nome do RecordStore.


int getNextRecordID()

Retorna o recordId do prximo registro a ser adicionado no record store.


int getNumRecords()

Retorna o nmero de registros presents em um record store.


byte[] getRecord(int recordId)

Retorna uma cpia do dado armazenado em um registro especificado pelo seu recordId.
int getRecord(int recordId, byte[] buffer, int offset)

Retorna o dado armazenado em um dado registro.


int getRecordSize(int recordId)

Retorna o tamanho em bytes dos dados presents no registro.


int getSize()

Retorna o tamanho, em bytes, que o record store ocupa.


int getSizeAvailable()

Retorna a quantidade de espao adicional (em bytes) disponvel, para que o record store cresca.
int getVersion()

Cada vez que um record store modificado (registro adicionado, modificado, deletado), sua verso incrementada.
static String[] listRecordStores()

Retorna um array com os nomes dos record stores gerenciados pela MIDlet suite.
static RecordStore openRecordStore(String recordStoreNome, boolean criaSeNecessario)

Abre (e, possivelmente cria) um record store.


void removeRecordListener(RecordListener listener)

Remove um RecordListener especfico.


void setRecord(int recordId, byte[] novoDado, int offset, int numBytes)

Configura os dados de um dado registro.

14.1 Gerenciando os Record Stores do dispositivo Antes de fazer qualquer operao com um Record Store, preciso cri-lo, ou, se j esto presentes no dispositivo, abrir cada um deles. Sendo

assim, o primeiro passo chamar o mtodo openRecordStore(String nome, boolean criar). O primeiro parmetro o nome do Record Store, este, tem que ser nico dentro da MIDlet Sute, alm disso, no pode ultrapassar o limite de 32 caracteres. Veja o exemplo da Listagem 29, nele, criamos um banco de dados chamado Paises, se ele ainda no existir, ser criado, isso porque o lltimo parmetro est marcado como true.
1: RecordStore rs = RecordStore.openRecordStore("Paises",true);

Listagem 29: Mtodo para abrir um Record Store.

A classe RecordStore traz alguns mtodos para gerenciamento, como os mtodos getVersion, getLastModified e getSize. O primeiro retorna a verso do Record Store. A verso atualizada a cada vez que uma operao de insero, atualizao ou remoo de registro efetuada. O segundo mtod retorna a data e a hora da ltima modificao no Record Store e, por fim, o mtodo getSize() retorna o tamanho, em bytes, que o armazm de registros est ocupando no dispositivo. Assim como existe um mtodo para abrir e/ou criar um Record Store, tambm existem os mtodos para fechar e deletar o mesmo. A linha 1 da Listagem 30 apresenta o cdigo para fechar um recor store, logo a seguir, mostrado o mtod para deletar um record store, passando como parmetro o nome utilizado na sua criao.
1: rs.closeRecordStore(); 2: RecordStore.deleteRecordStore("Paises");

Listagem 30: Mtodos para fechar e deletar um Record Store.

14.2 Inserindo, atualizando e detelando registros Para acompanhar a explicao destas trs operaes, veja a Listagem 31. O mtodo para inserir um novo registro eu um Record Store o addRecord(byte, offset, numBytes). O primeiro parmetro define um vetor de bytes, criado na linha 2. O segundo parmetro indica a partir de qual ndice do vetor os dados sero usados e, por fim, o ltimo parmetro indica o nmero de bytes que do vetor que sero gravados no registro. Na linha 5 criamos uma nova String, a linha 6 atribui um novo vetor de bytes a varivel info e, a linha 7 atualiza o registro com id 1 presente no record store da varivel rs. Perceba que os ltimos trs parmetros so exatamente iguais ao mtodo de insero, a diferena est no primeiro parmetro a mais, onde definido o id do registro a ser atualizado. Finalmente, a linha 9

mostra o mtodo necessrio para a deletar um registro. Seu nico parmetro define o id do elemento a ser removido.
1: String appt = "Brasil"; 2: byte info[] = appt.getBytes(); 3: rs.addRecord(info,0,info.length); 4: 5: String newappt = "Argentina"; 6: info = newappt.getBytes(); 7: rs.setRecord(1, info, 0, info.length()); 8: 9: rs.deleteRecord(1);

Listagem 31: Mtodos de insero, atualizao e remoo de registros em um Record Store.

Porm, se a idia for inserir informao em um registro que contenha campos, como uma agenda por exemplo, onde teremos o nome da pessoa e seu nmero de telefone. Teramos que inserir uma string com ricardo1189695976? No, felizmente existem duas classes que nos auxiliam em muita na insero de registros que apresentam campos virtuais. As classes so ByteArrayOutputStream e DataOutputStream. A Listagem 32 auxiliar na explicao. O primeiro passo criar as duas instncias das classes referidas (linhas 1 e 2). Tambm necessrio criar um vetor de bytes (linha 4). A seguir, com uma instncia da classe DataOutputStream podemos inserir tipos de dados em uma sada que ser gravada no registro do record store. Nas linhas 6 e 7 estamos usando o mtodo writeUTF, usado para inserir Strings, porm, tambm podemos utilizar o writeInt por exemplo, para valores do tipo int. Posteriormente, necessrio chamar o mtodo flush (linha 9). Atravs do mtodo toByteArray da classe ByteArrayOutputStream geramos um vetor de bytes, deste ponto em diante o processo de insero no record store igual.
1: strmOutBytes = new ByteArrayOutputStream(); 2: strmDataOutTypes = new DataOutputStream(strmOutBytes); 3: 4: byte[] record; 5: 6: strmDataOutTypes.writeUTF(nome); 7: strmDataOutTypes.writeUTF(numero); 8: 9: strmDataOutTypes.flush(); 10: 11: record = strmOutBytes.toByteArray(); 12: 13: rsAgenda.addRecord(record, 0, record.length); 14: strmOutBytes.reset(); 15: 16: strmOutBytes.close(); 17: strmDataOutTypes.close();

Listagem 32: Mtodos de insero, atualizao e remoo de registros em um Record Store.

14.3 Enumerando registros O programador no saber de ante-mo os ids utilizados pelos registros, para isso, possvel utilizar a classe RecordEnumeration, com ela, possvel enumerar os registros presentes em um record store (se um filtro aplicado, a enumerao se dar sobre os registros retornados pela filtragem). A enumerao mantm uma ordem lgico dos ids dos registros, sendo possvel iterar sobre seus elementos. Veja na Listagem 33 uma forma de utilizao da RecordEnumeration. A primeira linha a chave da listagem, a varivel rs uma instncia de record store, atravs do mtodo enumerateRecords(comparador, filtro, manter) capturamos uma instncia de RecordEnumeration, a seguir, na linha 2, cria-se um lao enquanto estiver elementos no enumerator. Verifica-se isso com o mtodo hasNextEelements(). Por fim, a linha 3 utiliza o mtodo nextRecord o retorno o prximo registro da iterao.
1: RecordEnumeration re = rs.enumerateRecords(null, null, false); 2: while (re.hasNextElement()) 3: Byte nextRec[] = re.nextRecord();

Listagem 33: Enumerando registros de um Record Store.

14.3 Criando filtros na enumerao de registros Ao enumerar os registros de um record store, possvel criar filtros, recuperando apenas parte das informaes persistidas seguindo uma especificao pr-estabelecida. Para isso, basta ter uma classe que implemente a classe RecordFilter, esta classe tambm deve ter, de forma obrigatria, a implementao do mtodo matches (byte[] candidate). A Listagem de cdigo 34 traz a implementao de uma classe Filtro que foi utilizada na construo de um aplicativo de agenda de telefones. Sempre que a classe chamada com o operador new, seu construtor recebe uma varivel String linha 9. O mtodo matches (linha 12) ser executado a cada registro presente no record store. A cada registro recuperado o nome da pessoa (linha 18), em seguida, feito um teste para ver se este nome comea com a String configurada como filrtro (linha 19). Se o teste booleano retorna verdadeiro, o mesmo valor retornado pela funo, caso contrrio, o valor false retornado.

1: class Filtro implements RecordFilter 2: { 3: private String filtro; 4: private ByteArrayInputStream strmBytes; 5: private DataInputStream strmDataTypes; 6: 7: public Filtro(String filtro) 8: { 9: this.filtro = filtro; 10: } 11: 12: public boolean matches(byte[] record) { 13: try 14: { 15: strmBytes = new ByteArrayInputStream(record); 16: strmDataTypes = new DataInputStream(strmBytes); 17: 18: String s1 = strmDataTypes.readUTF(); 19: if (s1.startsWith(filtro)) 20: return true; 21: else 22: return false; 23: } 24: catch (IOException e) 25: { 26: return false; 27: } 28: } 29:}

Listagem 34: Enumerando registros de um Record Store.

Agora veja o cdigo da Listagem 35, faa uma breve comparao com a Listagem 33. Na primeira listagem, tnhamos como parmetros do mtodo enumerateRecords os valores null e null, ou seja, no especificamos nenhum meio de ordenao e nenhum filtro. Na ltima listagem, passagem uma instncia de uma classe Filtro, mostrada na Listagem 33 e, uma instncia da classe Ordenador, que ser vista posteriormente.
1: reAgenda = rsAgenda.enumerateRecords(new Filtro(filtro), new Ordenador(), false); 2: while (reAgenda.hasNextElement()) 3: { 4: 5: }

Listagem 35: Enumerando registros de um Record Store.

Assim como criamos um teste utilizando o mtodo startsWith da classe String, poderamos ter usado um teste booleano simples com operadores: >, <, ==, dentre outros. Ou ainda, poderamos utilizar o mtodo

equals da mesma classe, se o filtro utilizado exigisse encontrar somente nomes exatamente iguais aos procurados. 14.4 Ordendo os registros Vimos anteriormente a utilidade dos filtros, agora veremos tambm como ordenar os registros encontrados em uma enumerao. A classe utilizada a RecordEnumeration. De forma anloga a RecordFilter, tambm preciso criar uma classe que herde diretamente de RecordEnumeration, e, de forma obrigatrio, implementar o mtodo compare(byte[] rec1, byte[] rec2). A Listagem de cdigo 36 mostra a implementao desta classe no uso do mesmo aplicativo da Agenda, onde os nomes devem ser ordenados na ordem crescente, usando o alfabeto como regra. O mtodo compare recebe sempre dois vetores de bytes que compreendem o registro do record store. A utilizao das classes ByteArrayInputStream e DataInputStream ser vista no prximo item deste livro. A linha 11 l um valor UTF, ou seja, um conjunto de caracteres que pode ser interpretado como uma String. Da mesma forma, na linha 16, usamos o mesmo mtodo para recuperamos o nome (a agenda composta por nome e nmero de telefone) do segundo registro. Depois de ter os nomes em duas variveis, s1 e s2, utilizamos o mtodo compareTo entre as duas Strings. Se s1 for menor que s2 (linha 18), significa que ela est a frente na ordenao, ou seja, ela est em uma posio seguinte. Se as duas forem iguais (linha 20), eles esto na mesma posio, ou, se s2 for menor, esta ltima varivel dever aparecer antes que a s1 na ordem alfabtica (linha 22). A classe RecordComparator traz algumas constantes que representam estes trs estados, so elas: FOLLOWS, EQUIVALENT e PRECEDES. A forma de utilizao da ordenao pode ser observada na Listagem 34, onde, ao enumerar os registros, passamos uma instncia da classe Ordenador no segundo parmetro.

1: class Ordenador implements RecordComparator 2: { 3: private ByteArrayInputStream strmBytes; 4: private DataInputStream strmDataTypes; 5: public int compare(byte[] rec1, byte[] rec2) { 6: try 7: { 8: strmBytes = new ByteArrayInputStream(rec1); 9: strmDataTypes = new DataInputStream(strmBytes); 10: 11: String s1 = strmDataTypes.readUTF(); 12: 13: strmBytes = new ByteArrayInputStream(rec2); 14: strmDataTypes = new DataInputStream(strmBytes); 15: 16: String s2 = strmDataTypes.readUTF(); 17: if (s1.compareTo(s2) > 0) 18: return RecordComparator.FOLLOWS; 19: else if (s1.compareTo(s2) == 0) 20: return RecordComparator.EQUIVALENT; 21: else 22: return RecordComparator.PRECEDES; 23: 24: } 25: catch (IOException e) 26: { 27: return RecordComparator.EQUIVALENT; 28: } 29: } 30:}

Listagem 36: Ordenando registros de um Record Store.

14.5 Recuperando registros Na insero de registros vimos duas classes que imitam a utilizao de campos, tornando a vida do programador mais fcil. Para a recuperao de registros de um record store tambm existem duas classes que tem a mesma funo, s que de forma inversa, ou seja, recupera-se campos presentes no registro e, no somente um vetor de bytes que dever ser tratado posteriormente. As classes so: ByteArrayInputStream e DataInputStream. Veja a Listagem 37 para um melhor entendimento. Na linha 3 criado uma instncia da classe RecordEnumeration. A linha 4 inicia um while enquanto estiver elementos no enumerador. A linha 5 recupera o vetor de bytes do prximo elemento presente no enumerador. Com o vetor de bytes podemos criar as instncias de ByteArrayInputStream e DataInputStream (linhas 6 e 7). Com o mtodo readUTF, da classe, DataInputStream possvel pegar duas Strings em sequncia, que, no caso

da agenda, seriam o nome e o telefone. Os mtodos a seguir servem para limpar e fechar as classes de stream e enumerao.
1: if (rsAgenda.getNumRecords() > 0) 2: { 3: reAgenda = rsAgenda.enumerateRecords(null, new Ordenador(), false); 4: while (reAgenda.hasNextElement()) { 5: recData = reAgenda.nextRecord(); 6: strmBytes = new ByteArrayInputStream(recData); 7: strmDataTypes = new DataInputStream(strmBytes); 8: 9: dados.addElement(new String[]{strmDataTypes.readUTF(), strmDataTypes.readUTF()}); 10: 11: strmBytes.reset(); 12: strmBytes.close(); 13: strmDataTypes.close(); 14: } 15: 16: reAgenda.destroy(); 17: 18: strmBytes.close(); 19: strmDataTypes.close();

Listagem 37: Recuperando registros de um Record Store.

Você também pode gostar