Escolar Documentos
Profissional Documentos
Cultura Documentos
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
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.
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.
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.
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.
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.
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:
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"); } }
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.
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)
por parmetro.
boolean isColor()
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
Requisita que o dispositivo vibre por um intervalo de tempo especificado por duracao.
Configura um listener para os Commands do Displayable, sobrescrevendo qualquer CommandListener previamente configurado.
void setTicker(Ticker ticker)
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"); } }
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.
Cria um novo objeto Command com um rtulo curto e um longo, alm do seu tipo e prioridade.
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 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(); } } }
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.
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.
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) { } }
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()
tipo do Alert.
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)
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).
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.
Retorna o tamanho mximo (nmero de caracteres) que podem ser armazenados no TextBox.
String getString()
que
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++; } }
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).
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.
List(String titulo, int tipoLista, String[] elementos, Image[] iconesElementos) Cria um novo objeto List, especificando o ttulo, o tipo da lista,
Method Summary
int append(String string, Image imagem) Adiciona um novo item ao objeto List. void delete(int indice)
Retorna a fonte usada pela aplicao de um elemento especifcado pelo parmetro recebido.
Image getImage(int indice) Retorna o objeto Image indice.
parmetro.
int getSelectedIndex()
void insert(int indice, String parteString, Image parteImagem) Insere um elemento na lista, colocando ele no ndice.. boolean isSelected(int indice)
no.
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) { } }
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.
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.
dentro do Form.
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)
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()
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"); }
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
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.
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.
Cria um novo ChoiceGroup, especificando seu ttulo, o tipo e um vetor com strings e imagens eu formam os elementos do componente.
Recupera o estado dos elementos de um ChoiceGroup, armazendo-os em um vetor de booleanos recebido por parmetro.
int getSelectedIndex()
Configura o elemento referenciado pelo sue ndice, atualizando seu texto e sua imagem com os parmetros recebidos.
void setSelectedFlags(boolean[] arraySelecionado)
Para objetos ChoiceGroup do tipo MULTIPLE, ele simplesmente configura o estado de um elemento individualmente.
int size()
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.
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.
mtodos,
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.
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.
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.
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.
mximo
Retorna o tamanho mximo (nmero de caracteres) que pode ser armazenado no TextField.
String getString()
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).
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.
Cria um novo objeto, onde o clculo do calendrio baseado em um objeto TimeZone especfico. Padronizando o sistema de calendrio para local corrente especificado.
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.
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 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.
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) {} }
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).
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.
Gets the text string to be used if the image exceeds the device's capacity to display it.
int getAppearanceMode()
Gets the image contained within the ImageItem, or null if there is no contained image.
int getLayout()
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)
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)); } }
Figura 37: Exemplo de ImageItem no emulador da Srie 80 dos telefones celulares da Nokia.
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.
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.
perfil MIDP).
int getMaxValue()
Retorna um valor Boolean indicando se o item permite que o usurio modifique seu contedo.
void setDefaultCommand(Command cmd)
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) {
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.
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) { } }
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) {} }
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: }
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]; } }
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 superclasse, fornecendo uma maneira de suas subclasses especificarem seus rtulos.
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 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
uma ao de arrasto de ponteiro (canetas presentes em dispositivos touch-screen, como PDAs) ocorre dentro do item. um evento de pressionamento de
protected repaint(int x, int y, int largura, int altura) void Solicita que o item seja repintado a partir de um ponto
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
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.
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.
A seguir, duas tabelas so apresentadas, mostrandos as constantes da classe e alguns dos seus mtodos:
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)
e (x2,y2) usando a
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)
Configura o clip corrente para o retngulo especificado com as coordenadas passadas por parmetro.
void setColor(int RGB)
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.
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.
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:
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: }
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) { } }
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: }
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);
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?
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);
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.
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.
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);
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 :
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.
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:{ }
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.
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).
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:{}
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
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.
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.
Retorna uma cpia do dado armazenado em um registro especificado pelo seu recordId.
int getRecord(int recordId, byte[] buffer, int offset)
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)
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);
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");
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);
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();
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();
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:}
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: }
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:}
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();