1

Apostila de J2ME
versão 1.1 Juliano Carniel - juliano@portaljava.com Clóvis Teixeira - clv@portaljava.com

Tutorial J2ME Copyright® - 2005

2

Índice
- INTRODUÇÃO: ..............................................................................................................................4 - ENTENDENDO J2ME ....................................................................................................................5 - CONFIGURATION.........................................................................................................................5 - PROFILES........................................................................................................................................5 - SEGURANÇA ..................................................................................................................................7 - TECNOLOGIAS WIRELESS ........................................................................................................8 - DIFERENÇA ENTRE MIDP 1.0 E 2.0..........................................................................................9 - API'S .................................................................................................................................................9 - CRIANDO PROJETOS, COMPILANDO E EXECUTANDO ...................................................9 - CICLO DE VIDA DE UMA MIDLET ........................................................................................13 - INTERFACE ..................................................................................................................................13 - COMMANDS .................................................................................................................................14 - TEXTBOX ......................................................................................................................................16 - TICKERS........................................................................................................................................16 - FORMS ...........................................................................................................................................16 - ITEM ...............................................................................................................................................17 - LISTS ..............................................................................................................................................19 - IMAGENS ......................................................................................................................................20 - ALERTS..........................................................................................................................................20 - CONEXÕES ...................................................................................................................................21 - SMS VIA SERVIDOR ...................................................................................................................22 - ARMAZENAMENTO EM CELULARES (RECORDSTORES) .............................................23 - CANVAS .........................................................................................................................................25 - CODIFICANDO ............................................................................................................................29 CÓDIGOS EXEMPLOS..................................................................................................................31
Tutorial J2ME Copyright® - 2005

3 EXEMPLOCOMMANDSANDTICKER ..................................................................................................31 EXEMPLOLISTANDALERT ...............................................................................................................33 EXEMPLOTEXTBOX.........................................................................................................................36 EXEMPLOFORM1 .............................................................................................................................38 EXEMPLOGAUGE .............................................................................................................................40 EXEMPLOCONNECTIONIMAGE .........................................................................................................43 EXEMPLOHTTPCONNECTION ...........................................................................................................46 EXEMPLOCANVAS ...........................................................................................................................49 REFERÊNCIAS BIBLIOGRÁFICAS ...........................................................................................51 COPYRIGHT ...................................................................................................................................52

Tutorial J2ME Copyright® - 2005

4

Apostila de J2ME
- Introdução:
Comecemos com uma pergunta básica, porém não menos importante. O que vem a ser esse J2ME? E para que serve? Java 2 Micro Edition é uma API Java voltada para micro aplicativos que rodam em micro processadores assim como os dos celulares e PDA s. Neste Tutorial vamos tratar da Tecnologia J2ME MIDP 1.0 voltada para aplicações gráficas, porém não vamos tratar de jogos aqui, embora após a leitura deste, você pode ter um embasamento para começar a desenvolver algo na área. As aplicações criadas usando-se MIDP são chamadas MIDlets (assim como Servlets e Applets). Usamos os programas: - Wireless Tollkit que é um software gratuito feito pela Sun para simplificar o ciclo de desenvolvimento do J2ME o qual pode ser encontrado em http://wireless.java.sun.com/allsoftware/ (é necessário que você já tenha o j2sdk instalado http://java.sun.com/j2se), você ainda pode baixar outros emuladores encontrados na mesma pagina do Wireless Toolkit para posteriores testes. - E o editor GEL que é free, e é um ótimo editor facilitando muito na edição com auto-complete de métodos e muitas outras facilidades que este programa provê, e pode ser encontrado em www.gexperts.com . Caso você já tenha algum outro programa como o Eclipse (www.eclipse.org), por exemplo, pode-se usa-lo também fazendo as devidas modificações, existe um plugin chamado EclipseME (http://eclipseme.sourceforge.net) que pode ser utilizado para auxiliar nesse desenvolvimento. A abordagem desta apostila foca-se no MIDP1.0 e CLDC1.0 por ainda ser maioria no mercado e também para que possamos contemplar bem os recursos para se desenvolver uma aplicação J2ME. Se fossemos discutir a fundo os novos recursos do MIDP2.0 e CLDC1.1 teríamos que dar uma abrangência muito maior do que a que já damos nesta apostila e esse não é o nosso objetivo para esta versão do material.

Tutorial J2ME Copyright® - 2005

5

- Entendendo J2ME
J2ME basicamente é dividido em configurations, profiles e API's opcionais.

- Configuration
A configuration mais básica do J2ME é o CLDC (Connected Limited Device Configuration) e também a mais importante pois ela da base para a outra configuration, CDC (Connected Limited Configuration) a qual prove algumas funcionalidades a mais, e requer um pouco mais de hardware. Mas o que vem a ser essa tal de configuration? Bom, ela basicamente provê algumas bibliotecas básicas e a VM (virtual machine), ou seja, a parte mais basica que necessita estar presente em todo e qualquer dispositivo que suporta essa tecnologia.

- Profiles
Um profile, nada mais é que uma série de API s padrões que combinadas com alguma configuration, no nosso caso o CLDC, prove um serviço completo para que aplicações possam ser rodadas. E a profile que nós iremos trabalhar é a MIDP. Celulares, em sua quase totalidade hoje no mercado trabalha com o MIDP1.0 e CLDC1.0. Para entendermos melhor, pensemos da seguinte maneira, Profiles são mais específicos que configurations, e fazendo analogia a um velho exemplo, temos uma
Tutorial J2ME Copyright® - 2005

CLDC como já vimos. rege as configurações para aparelhos extremamente pequenos. embora já nos faz analisar melhor códigos e métodos usados. Podem haver vários Profiles vamos citar dois aqui os quais são os mais importantes para este estudo. Como já foi citado. MIDP (Mobile Information Device Profile) e também o PDAP (Personal Digital Assistant Profile) e ambos estão acima do CLDC. o que nos faz pensar muito em termos de aplicações que podem rodar neles. mas mesmo assim pequenos. mas muito mesmo. E também a conexão lenta. tipicamente de Tutorial J2ME Copyright® . Você não leu errado e nem nós trocamos unidades de medidas. o qual fica acima das diretrizes J2ME juntamente com CDC (Connected Device Configuration) o que rege as configurações para aparelhos um pouco maiores. porém é muito difícil dizer ao certo pois o acesso a informações desse tipo nas especificações dos fabricantes é bem restrito. a memória está realmente certa.6 abstração sobre o que é um carro e como ele é fabricado (configuration) e como um Ford é fabricado (profile). mais tecnicamente falando profile é baseado em configuration e ainda acima dos profiles estão as API's que na nossa analogia seria um modelo específico da Ford. e se tratando de aparelhos tops de linha podem chegar até 300MHz ou um pouco mais (até a composição desta matéria). E falando em memória relevemos também o processamento que é muito fraco. pois no mínimo 16MHz são requeridos. os quais despedem de muito processamento e uso de memória.2005 . existem dois "configurations". um configuration é o CLDC (Connected. e nos traz de volta a certas programações para DOS no que diz respeito à memória. que rege as configurações para aparelhos bem pequenos como celulares ou PDA's. Limited Device Configuration). ele foi desenvolvido para dispositivos de no mínimo 160KB e algumas dezenas de MHz de processamento.

8KB de memória não-volátil de para armazenamento de dados. . Tutorial J2ME Copyright® . e não pode acessar a memória correspondente às aplicações nativas do celular assim como é feito com os Applets.Pelo menos 192KB livres para Java.600bps para aparelhos TDMA/CDMA e de 128Kbps para GPRS/CDMA 1xRTT.2005 . ou programas maliciosos? Por meio do J2ME. No caso dos jogos de celulares. os quais dizem ter uma tela ampla de 96x54. Run Anywhere!".Segurança Uma pergunta freqüentemente feita é: Agora com programas rodando nos celulares não iremos ter problemas de vírus.Capacidade de entrada de dados seja por teclado (do celular). porém ja temos visto celulares sendo atacados por vírus que exploram falhas do Sistema operacional e não de uma aplicação J2ME.Possibilidade de enviar e receber dados em conexão possivelmente intermitente e banda reduzida. um pouco diferente do J2SE.Mínimo de 160kB de memória não-volátil para JAVA.32KB de memória volátil para tempo de execução. porém cai por terra a forte característica de vida do JAVA. . muito difícil. .7 9. . A maquina virtual tem um espaço independente de memória (sand-box). cada fabricante disponibiliza uma API específica para os jogos. podendo assim aproveitar melhor o desempenho do aparelho.Um processador de 16 bits ou 32 bits com um clock de no mínimo 16MHz. a (WORA) "Write Once. . perde-se um pouco a funcionalidade. apesar de ser mais seguro. teclado externo ou mesmo Touch-screen. . MIDP tem as seguintes características: . . .Uma tela de pelo menos 96x54 pixels (aqui já cai por terra a propaganda de muitos celulares. o que é o mínimo necessário).

Tutorial J2ME Copyright® . porém opera usando GPRS. e tanto esta tecnologia quando a GSM são conexão 100% ativa.Tecnologias Wireless Muitas pessoas ainda têm dúvidas sobre as diferentes tecnologias de celulares existentes. é separado voz de dados.gsmworld. ou seja.TDMA: (time division multiple access.terra.br/SeparataTELCO50. que é o que esta em vigor. Vamos tentar defini-las e diferencia-las em poucas palavras.8 Nota dos Autores: Pouco tempo antes da revisão dessa segunda versão da apostila. aquela que usa SymbianOS. apenas tenta se propagar para outros celulares. porém pelo provado pelo uso hoje dessas tecnologias. Um malefício provocado é gastar bateria do celular.com.htm e http://idgnow. para somente depois poder transmitir. . sendo que este não é o enfoque principal deste Tutorial. . Somente para estabelecer a conexão leva-se uns 8 segundos e a transferência de dados dá-se a 9.com.GSM: (global system for communication. ou seja.600bps(conseguindo-se taxa máxima). Além de a taxa de transferência que é maior chegando a 256Kbps usando CDMA 1xRTT. ou seja. ele não diferencia voz e dados então para navegar na internet(dados) você paga o mesmo preço que pagaria por fazer uma ligação de voz. Como foi falado acima. vemos que ele precisa de uma primeira conexão o que também despende alguns segundos. ou seja.CDMA: (code division multiple access. não existe este delay de conexão você requisita uma informação e ela vem diretamente. as conexões eram para ser 100% ativas. . Quem tem algum celular tdma sabe o quão caro e lento é isso.br/idgnow/telecom/2002/09/0043 ainda em. pois se propaga sozinho através da interface de Bluetooth do celular. ou acesso múltiplo por divisão de códigos).2005 . .sit. on-line todo tempo. ou seja. porém este worm não faz nada no celular. ou acesso múltiplo por divisão do tempo). para uma série específica da Nokia. www. O vírus. Caso haja maior interesse nas tecnologias de transmissão e na evolução e tudo mais que diz respeito recomendo estes sites http://www. se encaixa mais na qualidade de WORM. embora seja chamado de vírus. não danifica nada. pois fica com a interface de Bluetooth ligada e procurando alguém que responda para se retransmitir. tem as mesmas características da tecnologia CDMA.net . surgiu o primeiro vírus para celulares. ou sistema global de comunicação).

lcdui.1) java. MultiThreading (sem interrupt().0 são feitas através do protocolo http que no caso é inseguro no envio de informações.microedition.0) Opcionalmente.control (somente na 2.rochester.microedition.lang.lang. Protection Domains baseados em IP's e PKI's.rms javax.midlet javax.Criando projetos. e tratamento de sons.9 .microedition.0) javax.0 como classes para jogos. e algumas facilidades maiores da 2. o CLDC1.microedition.Object) Garbage collector existe. resume() e stop()) Sem thread groups e thread Deamons . A versão 1.microedition.com/ohommes/MathFP .ref (somente CLDC1.1 traz bastante recursos.API's A CLDC 1. e já se aproxima mais do J2SE.pki (somente na 2.io javax.util javax. java. fabricantes podem fornecer API's JAVA para acesso a partes especificas de cada aparelho.media.0) javax. porém mesmo com a versão 1.Diferença entre MIDP 1.lcdui javax.lang java.0 está implementado o https (ssl) conexão com criptografia que já é conhecida de todos.media (somente na 2.1 do CLDC já possui suporte a ponto flutuante.microedition. já na 1.game (somente na 2. como todos sabemos a cada versão mais nova é sempre incrementado mais funções. Compilando e Executando Tutorial J2ME Copyright® .0 não possui suporte a ponto flutuante.io java. a não ser os fornecidos pela JVM nativa. Sem RMI e sem JINI Sem métodos nativos. pause().microedition. porém não executa método automático. Além desses métodos a mais. se desejas trabalhar com contas. . ou seja. por exemplo.rr.microedition. com Permissions Types. Você tem ainda outras restrições como: Sem user classLoading Sem finalização de objetos (finallize() de java.0 você pode baixar programas específicos pra isso como esse programa encontrado em http://home.0 Existem algumas diferenças entre as versões.0) javax. as conexões no CLDC1.0 e 2.2005 . temos a diferença na comunicação de dados que é o mais interessante aqui como. e valores reais terás que manuseá-los em código mesmo. Aqui listamos os Packages disponíveis para as versões. Com relação à segurança.

10 Bom depois de muita teoria. Depois de tudo instalado corretamente. devemos primeiramente abrir o Wireless ToolKit e criar um Projeto. Tutorial J2ME Copyright® . Depois em Project Name defina o nome do seu projeto. e logo abaixo o nome da classe de sua midlet que deve ser igual ao nome do projeto. e a mais esperada por todos. O processo de desenvolvimento de MIDlet's é um pouco mais complexo do que de outros programas feitos em JAVA. a qual nos deu um embasamento melhor para sabermos o que estamos fazendo. Compilar. vamos a uma parte mais prática.2005 . Testar e/ou Instalar. Pré-Verificar. para isso clique em New Project. Empacotar. pois é feito segundo estes passos: Editar código fonte.

que é o icone que aparecerá no celular de sua aplicação você pode modificá-lo colocando o nome de uma figura personalizada. o qual você pode colocar o nome de sua empresa. para cada aplicação é criado uma árvore de diretórios conforme ilustrado abaixo. ou o que desejares.png. e sempre para qualquer aplicação deve-se por dentro do diretório /res.2005 . se ele é apto a rodar ou não seu programa. Em seguida abrirá uma tela que contém informações sobre a sua aplicação. pois é por esse arquivo que o celular reconhecerá seu aplicativo antes de ser baixado. apenas lembre-se que a figura deve ficar no devido diretório (path_WTK/apps/Sua_Aplicacao/res). a única coisa que poderias mudar seria o Vendor Name.11 Feito isso ele terá criado vários diretórios dentro de path_WTK/apps/Sua_Aplicacao/. tem um link para uma figura . (aconselho a não mudar o que está lá). Tutorial J2ME Copyright® . Se vocês verificarem a última aba desta tela (aba MIDlets).

pode ser encontrado em www. métodos não usados e ainda inserem dados ilegais ou questionáveis para confundir Descompiladores. BUILD. Após a criação do projeto. e quanto menor sua aplicação for. Tutorial J2ME Copyright® . Para isso usamos o Obfuscator que é usado para diminuir o tamanho dos arquivos eliminando redundância e também para evitar engenharia reversa. depois de baixado você deve copiar o arquivo retroguard. e finalmente. removem classes.12 Existem dois botões que serão muito utilizados por nos.jar dentro do diretório bin do wirelessToolkit. Este programa. e RUN. Para criar um pacote obfuscado você precisa de algum programa Obfuscator.com. melhor será para o celular. estamos aptos. os quais são auto-explicativos. renomeia classes.retrologic. o Retroguard. pois em alguns celulares a sua aplicação pode acabar não funcionando. Tome um pouco de cuidado com os obfuscators. a criar nossos códigos. Obfuscator Como vimos dispositivos celulares possuem memória muito reduzida. variáveis e métodos para nomes mais compactos. (Ex: c:\WTK104\bin). um bom programa.2005 .

somente fica disponível após o inicio da Aplicação (startApp()). Assim como a AM pode pausar a aplicação e esta a si mesma. As aplicações são desenvolvidas com uma certa abstração de tela. As classes de cada aplicativo estão em um arquivo JAR. cores. pois o método getDisplay().2005 . que terá todas as informações as quais já vimos anteriormente. como disposição em tela por exemplo. o qual coloca a midlet no estado Active. Assim que a MIDlet é invocada.Ciclo de Vida de uma MIDlet O Aplication Manager (AM) de cada dispositivo é quem vai controlar os aplicativos a serem instalados. geralmente contida no método startApp(). pois os comandos e insersão de dados são feitos através dos botões do celular. Tutorial J2ME Copyright® . contendo a VM. touch-Screens e outros aspectos. teclados. a qual é obtida pelo método getDisplay(). Enquanto ela estiver executando o AM pode pausar ela invocando o método pauseApp() no caso de uma chamada sendo recebida. pois dispositivos variam de tamanho de tela.13 . ocorre o mesmo com o DestroyApp() que é invocado pela AM para fechar a aplicação ou até mesmo pode ser fechada através da própria aplicação invocando o notifyDestroyed(). A aplicação pode pausar a si mesma. Já no desenvolvimento de jogos a aplicação é bem mais específica. .Interface As MIDlets devem poder ser executadas em qualquer dispositivo. A tela do dispositivo é representada por uma instância da classe Display. Nessa instancia de Display são inseridos heranças de Displayable. ou SMS chegando. e isto não é sabido previamente. bastando invocar notifyPaused(). o qual vem acompanhado de um descritor JAD. o AM invoca o método startApp(). sem alterações porém isso torna-se bastante difícil na parte de Interface com usuário. onde e como serão armazenados e como serão executados. pois o desenvolvedor precisa conhecer o dispositivo previamente para melhor aproveitamento de recursos. As aplicações descobrem isto em Runtime e se comportam de maneira apropriada a cada celular.

os quais são adicionados a componentes visuais.14 public void startApp() { Display d = Display. itens de menu.getDisplay(this). Repetir. objetos já instanciados. botões e Tutorial J2ME Copyright® .Commands Os commands como vimos. Decidir qual Displyable mostrar em seguida. Low-level API's que engloba a classe Canvas e suas heranças. As ações do usuário são gerenciadas por comandos (commands). O ciclo básico de uma MIDlet pode ser definido por: Mostrar um Displayable. . pois são classificados como objetos de Interface. Sua aplicação básica é na troca de Displayables. as quais proporcionam uma área livre para gráficos. Esperar por Ação do Usuário.. são usados para interação do usuário com a aplicação. E também temos as classes Screen e Canvas as quais podemos dividir em duas classes: High-level API's que engloba a classe Screen e suas heranças. } Na tela são mostrados componentes. .. que podem ser: softkeys.2005 . os quais são acionados por elementos reais do dispositivo. os quais são chamados pelo método setCurrent() o qual seta o objeto que será mostrado.

os quais ficarão dentro de um método chamado commandAction. Geralmente possui-se dois botões de SoftKeys. pois se houver mais commands que botões eles são agrupados e é aberto um menu.comando1) { .BACK. ou seja. Command(String Label. As ações dos commands são totalmente dependente do código. int Type.OK. a prioridade 0 (mais prioritário) indica que esse command deve ser mostrado nas softKeys. t1.TextField. que vem como herança quando a MIDlet herda CommandListener. 0). ele vai ficar onde normalmente fica os comandos de Exit do próprio celular.addCommand(ComandoSair). Command. Para cada objeto que herda de Diplayable existem os métodos addCommand(Command) e removeCommand(Command). } } Tutorial J2ME Copyright® . sem uma função única. comandos são adicionados a Displayables. ou seja. por exemplo. porém isso não significa que você precisa só ter dois commands sendo implementados. os quais são auto-explicativos. int Priority).EXIT. pois em runtime é que eles irão definir o local apropriado para se posicionarem na tela. Command... Displayable d) { if (c==this. ou seja. . t1. //comando feito acima Método commandAction public void commandAction(Command c.setCommandListener(this). ou em primeiro lugar no menu.15 dispositivos de acionamento. Type: tipo do comando. public void setCommandListener(CommandListener) Exemplo: TextBox t1 = new TextBox( Texto . cada displayable pode possuir um CommandListener o qual é invocado assim que um command é acionado. 10. Command.SCREEN. Os commands são geralmente relacionados a SoftKeys ou SoftButtons. O tratamento dos commands é feito com o conceito de Listeners. Dica: busque sempre a utilização dos correta dos tipos de Commands (Command. você terá que implementar a ação de cada command selecionado. Command. etc).2005 . e navegação em geral.EXIT.ANY). Os commands tem três propriedades: Label: texto mostrado ao usuário na interface. se um command é setado com o tipo EXIT. Priority: prioridade dos comandos que são utilizados para mostrar os comandos mais utilizados com maior facilidade. Ex: ComandoSair = new Command( Sair . Esses commands são entidades abstratas e podem ser adicionados arbitrariamente para cada elemento Screen ou Canvas. que são botões existentes nos celulares os quais são usados para menus. Para isso que serve a prioridade setada nos botões.

int constraints). // Displayable d = .16 . int tam_Max. mas com as limitações da MIDlet é claro. pois cada um implementa isso da sua maneira. . e de qualquer outro programa que é deixar o usuário feliz e menos cansado e entediado. Exemplos: TextBox t1 = new TextBox( Nome: . e o ticker tomara mais uma linha para si. ele serve para poder-se colocar mais de um componente na tela. Um form tem a mesma função de um Container em AWT/SWING. o qual pode conter mais de um controle de interface chamados Item. Apesar de haver rolagem automática quando todos os objetos não cabem na tela. onde: Titulo é mostrado no topo da tela. Texto é mostrado dentro do textbox. ou algo de enfeite que você queira colocar.2005 .ANY). e por isso temos que aprimorar essa técnica e manter o bom padrão de uma MIDlet. O recurso de Ticker serve para algum texto informativo que possa ser importante.Tickers Ticker nada mais é que um texto que corre no topo da tela. como string inicial. O construtor de um TextBox é: public TextBox(String titulo..TextBox É um componente básico que serve para entrada de texto(string) em celulares. a qual não poderá ser usada. e por isso não deve se tornar uma prática corriqueira. .. TextField. pois o usuário muitas vezes não irá saber se há mais objetos a serem preenchidos. 20. pois a rolagem dos forms tende a ser confuso nos dispositivos. ANY(para numeric e texto). d. etc. TextBox t2 = new TextBox( Nome: . além de tornar seu aplicativo esteticamente mal feito.ANY | TextField.PASSWORD). . a tela do celular já é pequena para sua aplicação. Para criarmos um form temos duas sobrecargas: Tutorial J2ME Copyright® . E os métodos para manuseio dessas Tickers não poderiam ser outros senão: public void setTicker(Ticker ticker) public Ticker getTicker . Mas lembre-se. TextField. que determinam que tipo de dado o campo aceitará ex: NUMERIC. ficar lembrando toda hora. cuidado para não deixar um form muito grande com muitos componentes. 30. semelhante as tickers de mercados de ações. Constraints são as constantes da classe TextField.Forms Form é uma herança de Screen e Displayable. Sua criação é simples. PASSWORD(mascara o texto). e semelhante ao <marquee> de html. tam_Max tamanho máximo de caracteres que será alcançado pelo textBox.setTicker(ticker). Todos sabemos o quão entediante é a entrada de dados em celulares. Ticker ticker = new Ticker( Esta mensagem deve passar na tela ). String texto.

set(int Indice. existem os métodos de manipulação: getLabel(). setText().17 public Form(String Titulo). para todos os exemplos abaixo: Form form = new Form( Form de teste ). Vamos relata-los aqui. e cada um com sua determinada função. insert(int Indice. Para este Item. Item[] itens). Ex: StringItem strItem = new StringItem( Nome: form. Esses diversos tipos de itens estendem da classe Item. Esses itens são inseridos em forms. getText(). . public Form(String Titulo. Lembre-se que o método append adiciona um novo item no final da lista. setLabel(). onde Codigo é a parte Label. eles podem ter comandos associados a eles. podem ou não ser mostrados.Item Como já foi falado existem vários tipos de itens. Como vimos os forms recebem itens os quais são divididos em diversos tipos cada um com sua finalidade. . Os métodos de trabalho com os forms são: append(Item item). A partir de agora vamos usar o mesmo form que criaremos agora. Juliano ). Os itens podem ser adicionados e removidos mesmo com os forms sendo mostrados. e o método insert adiciona um item no índice indicado movendo os outros existentes para baixo. Ex: Código: 1. Text ). e 1 é a parte Texto. Item item). eles podem ou não ter um Label. StringItem( Label: . delete(int Indice). StringItem nada mais é que um simples Label com um texto. Tutorial J2ME Copyright® .append(strItem).2005 . Item item).

*somente existentes no MIDP 2. setString(). Existem dois tipos de gauges. true. TextField. Tutorial J2ME Copyright® .TIME . Gauges É uma representação gráfica de um valor inteiro.createImage( /foto. Os layouts são constantes da classe. ImageItem. int TamMax. setValue(). ou melhor exemplificando um campo para preencher. URL). pelos comandos getMaxValue(). Ex: DateField data = new DateField( Data: . ImageItem mostra a instância de uma Imagem dentro de um form. Para este item existem os métodos de manipulação: getString().2005 . As constraints são as mesmas do TextBox (ANY. public Gauge(String Label. e podem ser: LAYOUT_DEFAULT. form. ou seja. . int ValorInicial). que pode ser: .ANY). LAYOUT_NEWLINE_BEFORE*. String Text. EMAILADDR. Ex: Gauge g = new Gauge( Gauge Interativo . PHONENUMBER. ImageItem(String Label. int ValorMaximo.LAYOUT_DEFAULT.0 Ex: Image img = new Image.DATE_TIME public DateField(String Label. NUMERIC. e como ele será mostrado depende da implementação de cada aparelho. LAYOUT_LEFT. int modo). Alt Text ). String texto_alt).append(tf). horas ou ambos. form. DateField. Image imagem. LAYOUT_NEWLINE_AFTER*). um texto alternativo e pode ser posicionado segundo um layout. int Layout. o interativo. boolean Interativo.DateField. TextField(String Label. como irá aparecer é por conta do Celular e o programador não tem controle sobre isso. int Constraints) Ex: TextField tf = new TextField( Digite seu Nome: 30. No construtor deve ser especificado a Label e o tipo de dado. Os valores podem ser alterados em tempo de execução. img. LAYOUT_RIGHT.DateField. 20. e Não interativo controlado somente pelo programa. .DATE . setMaxValue(). PASSWORD.png ). DateField É uma interface usada para datas.18 TextField é uma string editável. getValue(). Este item possui um label.DateField. 1). LAYOUT_CENTER.append(imgItem). que permite a ação do usuário sobre seu valor. você precisa já de um objeto Image.DATE ). ImageItem imgItem = new ImageItem( Foto .

Quando é selecionado um item em uma lista Implicit. Os tipo de listas são Exclusive e Multiple. que lembra uma lista de Radio. Aplicação pode tratar eventos de alteração de estado em Itens Interface ItemStateListener método public void itemStateChanged(Item item) Registra-se o listener com o método: setItemStateListener(ItemStateListener listener) . Já na MIDP 2. as quais permitem ao usuário selecionar itens (elements) de uma lista. Image[] imagens) Quando uma lista tornar-se grande demais para a tela. Esses elementos podem ser representados tanto por Strings quanto por Imagens. EX: Tutorial J2ME Copyright® . será criado uma rolagem. a qual não cabe a nós implementa-la. int tipo. Append: inclui um elemento ao final da lista. permite somente a seleção de uma opção e para seleciona-la deve-se usar um botão com um Command setado. delete: remove o elemento indicado pelo índice. int tipo) public List(String titulo. que nos permite selecionar várias opções. int tipo) public ChoiceGroup(String label. sendo que para esta List já foi anteriormente adicionando um CommandListener. Se este índice estiver no meio da lista. Existem duas sobrecargas para este construtor. o método CommandAction é chamado. String[] elementos. E ainda tem a list Multiple. ambos implementam a interface Choice. Existem três tipos de listas. no qual você pode iniciar os Arrays de elementos e de Imagens ou não. public ChoiceGroup(String label. String[] elementos. Cada elemento da list possui um índice. Exclusive e Multiple. os quais aparecerão em branco na tela. que deixa a lista semelhante a um menu DropDown. public List(String titulo. ela é por conta da VM. Para editar uma list. Esse índice inicia em 0. insert: insere um elemento em uma posição indicada por um índice. Implicit.19 ChoiceGroup é uma lista de escolhas semelhante a List. Exclusive.Lists Como o próprio nome diz são listas. int tipo. se utilizado. não poderá ser nulo.2005 . Implicit deixa você escolher uma opção e clicar no botão padrão de seleção ou em um command que você adicionar. existem alguns métodos que valem a pena ser comentados aqui. O array de elementos.0 é implementado o tipo POPUP. Que são: set: altera o elemento do qual o índice foi fornecido. que podem ser manejados para. Image[] imagens) Eventos de Itens Os Itens possuem eventos de alteração de Estado. que funciona como uma CheckList já conhecida de todos. porém não tem o tipo Implicit. ele força os outros elementos uma posição à frente. mas poderá conter elementos nulos.

somente para listas Implicit e Exclusive. int altura. ou VB.2005 . public static Image createImage(Image imagem) Somente um comentário à parte. Para se criar imagens mutáveis deve-se usar o seguinte método. . Imagens em MIDP 2. BMP. public static Image createImage(String nome) public static Image createImage(byte[] dados. quando não é usado o padrão.Imagens A especificação de MIDP determina que a implementação deverá ser capaz de manipular Imagens PNG. public static Image createImage(int largura. int transformacao) . a imagem é empacotada junto com o programa. ou seja. int x. ChoiceGroups. public int append(String elemento. String elemento. Image imagem). Porém. tem a mesma idéia de um alert de javascript. O segundo construtor obtém a imagem de um Arrray de Bytes. porém é muito raro você conseguir encontrar a especificação de cada aparelho para isso. int largura. ImageItems. Image imagem). public static Image createImage(Image image.Alerts Um alert nada mais é que uma mensagem informativa ao usuário. String elemento. Dois métodos bastante utilizados que valem a pena ser comentados são: public boolean isSelected(int indice): que me diz se o índice esta selecionado atualmente. o que não ocorre em todos os celulares. public int getSelectedIndex(): que me retorna o índice que foi escolhido. Essas imagens podem ser Mutáveis ou Imutáveis. ou qualquer outra linguagem. int altura) Lembre-se que as imagens passadas para Alerts. public void delete(int indice). Tutorial J2ME Copyright® . Imagens imutáveis podem ser criadas a partir de outras imagens mutáveis. esses dois construtores citados acima geram imagens imutáveis.0 podem ser criadas à partir de porções de outras imagens já existentes. obtido pelo método getGraphics(). quando ele é compilado e empacotado. Image imagem). até o tamanho indicado. e até mesmo PNG sem compactação. ele é basicamente uma telinha que mostra uma mensagem e logo depois sai da tela. int offset. o que torna muito difícil a programação com imagens. partindo da posição offset. int y. public void insert(int indice. int tamanho) O primeiro construtor busca o arquivo indicado pelo nome na pasta /res. outros com GIF.20 public void set(int indice. As mutáveis podem ser modificadas pelo Objeto Graphics. ou Lists devem ser Imutáveis. de sua aplicação no caso de uso do emulador. Alguns trabalham com JPG.

String texto. que funciona passando-se uma string de conexão para um método estático de Connector e retorna uma Connection com resultado. Asterisco(*) e Underscore(_) são mantidos.z. os quais também podem ser setados pelo desenvolvedor. temos os métodos GET. enquanto POST envia os parâmetro no header. onde xy é o valor Hexadecimal que representa os 8 bits menos significativos do caractere. porém o servidor só responde Tutorial J2ME Copyright® . ponto(. Já na CLDC 1. através de HttpConnection. para isso utiliza-se de URLEncoder. pouco confiáveis e intermitentes. Acesso não autorizado.microedition. E o alerta modal que aparece e fica esperando uma intervenção do usuário.microedition.. a..Conexões Sistemas móveis geralmente oferecem acesso a dados via conexões OTA(Over The Air). SocketConnection entre outros. ou Modal Alert. null). se usado o método setCurrent(atual. 0.2005 .21 Esses alerts podem ser tanto Timed Alerts. GET enviando parâmetros na URL. e na pior das hipóteses entedia o usuário. Ambos os métodos tratam das particularidades do protocolo Http como Headers. setCurrent(Alert). e possui vários tipos. as quais são definidas pela CLDC que é bem flexível. No Timed Alert. null.0 pode feita por HTTP. . o que nos dificulta um pouco essa transmissão de dados.Connector. Hífen(-). Image icone.setTimeout(5000).. Para isso ela usa o Package javax. e todo qualquer outro caractere é convertido em %xy. e pode ser obtido por getDefaultTimeout(). . Info. Ex: Alert alerta. Error. tempo qual é implementado na VM. Os parâmetros passados na url são codificados antes da transmissão o que garante integridade da informação e padronização. como Alarm. próximo).io e é baseada na interface Connection.FOREVER.Z. A MIDP possui mecanismos genéricos para acesso a rede. public Alert() public Alert(String titulo. você pode setar um tempo ou não o qual receberá o tempo padrão do aparelho. cada qual com seu ícone e som. ou ele irá voltar para a tela atual se for usado. porém algumas implementações particulares de celulares podem oferecer HttpsConnection.. podemos transforma-lo em modal adicionando ao parâmetro AlertType para Alert. O link real entre a interface Connection é feito através da classe javax.io.. alerta. Quando criamos um Timed Alert. alerta = new Alert( Alerta . A conexão na CLDC 1. porém essas conexões ainda são lentas.1 a obrigatoriedade é passada para a implementação do HttpsConnection. Revisando um pouco Http. este por estar já acostumado com uma conexão rápida e confiável.. e o HEAD que é idêntico ao GET.9. AlertType tipo) *Qualquer um ou todos os parâmetros do segundo construtor podem ser nulos. A. que transforma espaços em sinais de +. O Http trabalha com o processo de response/request incluindo Headers no processo. métodos e outros(RFC 2616). e também configurado por setTimeout(). Confirmation.). POST e HEAD. Alerts são criados com um tempo default para desaparecer. Warning. onde GET e POST buscam paginas.// timeout para 5 segundos O comportamento padrão de um Alert é mostar a próxima tela setada.

tais recursos são muito escassos.Mais simples e sem a preocupação com request headers Não use URLs hard-coded .Mantenha em application descriptors.Mantenha algum tipo de indicação de progresso para a interface com o usuário.2005 . com mensagens e indicações.HTTP_OK) { // processa resultado } Dicas: Sempre que for fazer uma conexão tenha uma thread separada para isso. não esqueça que se você espera um dado que não seja puro texto depois terá que converte-lo para seu estado original. Sempre que você estabelece uma conexão Http.jsp . inclusive Servlets que são geralmente utilizados como resposta para MIDlets) InputConnection ic = (InputConnection) Connector.SMS via servidor Tutorial J2ME Copyright® . InputStream is = ic. Ex: int status = -1. . if (status == HttpConnection. ic. Capture todas as exceções e proceda de forma razoável. Use GET ao invés de POST .com.br/suaPagina.close(). e caso você esteja esperando Strings como resposta. //aqui vai todo o processo de leitura (Veja nos Exemplos). (aqui pode ser qualquer pagina de qualquer extensão.getResponseCode(). Ex: String url = servidor.open(url).HTTP_OK. Libere memória e recursos assim que possível Em dispositivos portáteis. status = con. que será guardado em um array de bytes dependendo do tipo de dado que você espera do servidor. passando-se uma URL para o método open() da classe connector. .Acesso sempre toma tempo e pode ser demorado. e então ler os dados que foram retornados para você do Servidor e tratá-los conforme o que você precisa. A conexão GET funciona. e para isso você deve antecipadamente conhecer o formato de retorno da informação vinda do servidor.openInputStream(). . use StringBuffer. então você deverá obter os streams de conexão InputStream e OutputStream. é aconselhável que verifique o retorno dos Headers para saber se o retorno está ok. através de HttpConnection. da qual você irá receber o resultado como um HttpConnection ou um InputConnection (trataremos disso depois). prepare-se para o pior. o que permite alterar a URL sem recompilação Tenha certeza de que as exceções são tratadas adequadamente Redes wireless não são muito confiáveis.22 com Headers.

e assim que ele não for mais necessário. pois estas operações geram exceções como: RecordStoreException. possui apenas um id e um array de Bytes como local para armazenagem de dados. nada tem o que ver com a tecnologia J2ME. Tutorial J2ME Copyright® .rms. O parâmetro boolean da chamada do método indica que se true o RecordStore será aberta e se não existir será criada.openRecordStore( NomeQualquer . lhe permitindo o envio dessas mensagens.23 Bom em alguns fóruns já houve algumas perguntas sobre esse tópico e por isso vou comentar aqui algumas coisas. e então colocávamos em um ImageItem. A estrutura de Armazenamento do um RecordStore é bem simplória. que pode ser usada em suas aplicações para mandar mensagens. ou através de uma aplicação J2ME. sua criação é feita de forma simples e bem sugestiva.2005 . existe a API Wireless Messaging API (WMA). Assim como abrimos os recordStores temos que fecha-los. e então colocávamos o nome + carc_de_Controle +Foto[ ]. Porém. Já foi pedido. RecordStoreNotFoundException. Cada recordStore é identificado por um nome que deve ser único. Lembre-se também que sempre que for manusear um RecordStore você precisa usar try{} catch{}. Bom. esqueça! Se quiseres guardar mais que uma informação no array de Bytes. e então na hora de listar essas fotos tínhamos que trabalhar com cada registro percorrendo o array inteiro para primeiro listar o nome e depois a foto. a qual tinhamos que pegar o array e então criar um Image.RecordStore. nós trabalhamos com uma aplicação onde era preciso guardar um nome. colocando algum caractere de controle para seu armazenamento (Ex: Nome | Telefone). como poderia ser feito para mandar sms de servidores remotos.Armazenamento em celulares (RecordStores) A persistência em celulares é tratada com RecordStores que são conjuntos de registros e instâncias de javax. RecordStoreFullException. . da seguinte forma: RecordStore. O false apenas abre uma RecordStore existente. terás que trabalhar com este array. pois lembremos que trabalhamos com uma memória bem reduzida. true). fecha-lo.closeRecordStore().microedition. Somente como exemplo. também deve fechar os recordStores. e sempre que abrir um recordStore. O método para fechar o recordStore é nada mais que: ObjetoRecordStore. o que é necessário é um contrato com uma operadora a qual lhe fornecerá passagem livre do seu IP (computador remoto) pela rede dela. e uma fotografia. e com uma estrutura de linhas e colunas. E obviamente não há a necessidade de se construir uma aplicação pra isso sendo que os celulares já possuem isso nativo. Se você está acostumado com banco de dados. não esqueça que o método pauseApp.

por comparação de Arrays. porém o método pode ser usado como descrito abaixo: recEnum=rsExcluir. caso haja alguma alteração na RecordStore. continua existindo. getRecordSize(). usa-se o método hasNextElement() do RecordEnumeration. ou seja. public byte[] getRecord(int recordID) Nos retorna um array de bytes para podermos trabalhar com ele. os índices(IDs) dos elementos permanecem como estão.false). quando você quiser listar um RecordStore deve-se testar se ainda existe aquele record. o seu id. Importante saber que quando um record é excluído. que é retornado a cada inserção. usamos o método: public void deleteRecord(int ID) Quando deletamos um record.enumerateRecords(null. Para eliminar um Enumeration usa-se o método destroy(). Ou seja. Para deletar records. Este método pede parâmetros de comparação que não abordaremos agora. Apenas é possível reorganizar o Enumeration desse RecordStore. Este método é o: RecordStore.2005 . não sendo reorganizada a lista.enumerateRecords(). através do método. retorna todos os elementos e o "false" informa que esse Enumeration não será reorganizado automaticamente. Tutorial J2ME Copyright® . nextRecord(). Isso serve para que seja possível percorrer todos os elementos do recordStore a partir dos métodos da classe RecordEnumeration. Para controlar o laço de listagem desses records. retornando um RecordEnumeration.null.24 Cada registro pode ser lido ou modificado. Na Classe Recorstore temos um método que lista todos os records de determinada recordStore. segundo seu ID. previousRecord(). Os records podem ser "listados" a partir de RecordEnumeration. não há reorganização dos IDs.

que recebe como parâmetro um objeto da classe Graphics. pode-se forçar a renderização da tela chamando o método repaint(). Já a dependente de evento é usada para jogos pouco interativos. Em uma animação esse método repaint() fica dentro de um laço.25 . pois é isso que dá movimento ao jogo.2005 . renderizando a seqüência da animação. long period) Agenda uma tarefa para ser repetida no intervalo de period depois de Tutorial J2ME Copyright® . A partir da classe Graphics é que podemos desenhar figuras primitivas. Porém. void schedule(TimerTask task. Date time) Agenda uma tarefa específica em um determinado horário. As principais são: -dependentes de frame (quadro) -dependentes de tempo -dependentes de evento Cada uma tem sua aplicação. que nos permite trabalhar livremente com gráficos e figuras em mais baixo nível. pois o sistema é quem chama esse método. void schedule(TimerTask task. Para falarmos disso precisamos antes falar sobre a classe Timer. usando-se de recursos de Threads (processamento concorrente). A classe Canvas necessita que o desenvolvedor implemente o método paint(). long period) Agenda uma tarefa específica que será repetida num intervalo especificado por periodo a partir do horário definido por firstTime.Canvas Como já vimos. Mas o desenvolvedor não precisa se preocupar com esse objeto Graphics. void schedule(TimerTask task. usando o método schedule(). Esses tempos são definidos nos parâmetros passados ao método schedule(). A classe Timer serve para agendar tarefas. Date firstTime. que é a classe que irá fazer os frames serem colocados na tela a cada intervalo de tempo. é esta que iremos abordar aqui. imagens e textos em qualquer lugar dentro do espaço de resolução da tela do dispositivo. Mas como a estratégia dependente de tempo é considerada a mais importante delas para games. mas não comprometendo o tempo exato do fim da animação. Para um jogo há algumas estratégias de controle de movimentação que podem ser adotadas. Para jogos isso é muito importante. que não tenham transição gráfica intermitente. o mesmo não ocorre se usarmos a estratégia dependente de tempo. o que veremos é um frameskip maior. long delay. Canvas é uma classe estendida de Displayable. Também é a partir do Canvas que podemos desenvolver animações como jogos e apresentações. sendo que se for usada uma dependente de frame e seu celular for lento(baixa capacidade de processamento) a animação irá rodar mais lentamente. podemos fazer certas tarefas serem executadas em intervalos de tempo determinados. long delay) Agenda uma tarefa para executar uma tarefa depois de um determinado tempo. void schedule(TimerTask task. Canvas dá liberdade ao desenvolvedor.

setColor(255. g. int altura.this.largura=this. E então passar essa classe como primeiro parâmetro do método schedule() da classe Timer. Para parar a execução de determinada tarefa. g.getWidth(). é necessário criar uma classe que herde de TimerTask e implementar o método run() com a tarefa que você deseja que seja executada.getHeight().fillRect(0.lcdui. consulte a API do J2ME localizada no diretório docs do seu Wireless Toolkit) Ok.x=x.15).largura. g. Tutorial J2ME Copyright® . agora precisamos de alguém para mandar essa classe pintar o desenho na tela repetidas vezes numa constancia definida por um intervalo de tempo em milisegundos. private int y=0.altura). public MeuCanvas() { this. } // vamos criar métodos para mudarmos a posição do quadrado na tela public void setPositionX(int x) {this.microedition.0.setColor(0. } public void paint(Graphics g) { // pinta o fundo da tela de branco e o objeto de preto g.} public void setPositionY(int y) {this.2005 .26 delay.15. Agora que aprendemos a teoria.255.y.*.drawRect(x. para isso vamos usar a classe Timer e a TimerTask. vamos ver como ficaria uma aplicação com renderização dependente de tempo. Como já aprendemos. Existem outros métodos para agendar(para maiores informações.this. Primeiro cria-se uma classe que herda de Canvas para desenharmos o que queremos na tela.y=y. import javax.255).0).altura=this. class MeuCanvas extends Canvas { // posição do objeto que se movimentará na tela private int x=0.} } Temos a classe que irá pintar objetos na tela. utiliza-se o método cancel() descrito abaixo: void cancel() Finaliza o agendamento da tarefa. mas agora como agendar minha tarefa para executar repetidamente? Para agendar tarefas. int largura.0. this.

nos jogos de PC geralmente temos um jogo rodando a 20 frames por segundo numa maquina com geforce4 mx e o mesmo jogo rodando a 60 frames por segundo numa Radeon X850XT. Precisamos de duas tarefas para serem agendadas. int xs=1.canvas.largura. uma para a movimentação e outra para pintar na tela. que tarefas precisamos agendar para a nossa aplicação? Como nossa aplicação é dependente de tempo e não de frame.largura=this.largura-15)// . o objeto iria movimentar-se somente quando a tela fosse pintada.altura=this.15 pois esa é a largura do quadrado {xs*=-1. Por exemplo. // precisamos da altura e largura da tela para fazermos o algoritmo do movimento int largura.27 Ok. Tutorial J2ME Copyright® . temos que separar a tarefa de pintar na tela da tarefa de movimentar o objeto.util. Como assim? Não entendi! Veja.. no entanto a velocidade com que você atravessa um corredor no jogo é a mesma.} //incrementa ou decrementa as posições x+=(1*xs). pois se fosse assim. fazendo com que a movimentação do objeto dependesse do desempenho do aparelho em renderizar o desenho na tela. //precisamos do ponto de movimento e variáveis pra troca de sentido do movimento int x=1. Isso faz com que sua aplicação rode como deveria num celular rápido e rode de forma insatisfatória em outro mais lento. Vamos lá. public TarefaMovimento(MeuCanvas canv) { this. int altura. } public void run() { //troca o sentido do movimento if(x<=0 || x>=this.} if(y<=0 || y>=this. this. //temos que passá-la como parâmetro no construtor MeuCanvas canvas. class TarefaMovimento extends TimerTask { // como precisamos acessar o método setPositionX() e setPositionY() da classe MeuCanvas. import java.TimerTask. O fato de não mostrar todos os movimentos do objeto é comumente chamado de frameskip. Entendido isso vamos prosseguir.altura.altura-15)// . não podemos movimentar o objeto e pintá-lo na tela na mesma tarefa agendada.canvas=canv. y+=(1*ys).15 pois esa é a largura do quadrado {ys*=-1..2005 . int y=1. O objeto precisa se movimentar independentemente se ele está sendo mostrado na tela ou não. this.canvas. int ys=1.

canvas=new MeuCanvas(). import java.util..TimerTask. this. aquela que herda de MIDlet.canvas. } public void startApp() Tutorial J2ME Copyright® .Command.tr=new TarefaRenderizacao(this. this. // criamos as tarefas de movimento e renderização this. TarefaMovimento tm.sair).*.. import java.canvas). Vamos lá.tm=new TarefaMovimento(this. this.EXIT.repaint(). import javax.microedition. public TarefaRenderizacao(MeuCanvas canv) { this. } } Já temos as duas tarefas.*.28 // muda a posição na classe MeuCanvas this.canvas.canvas.canvas. this.addCommand(this.lcdui. this.2005 .timerRender=new Timer().util. } } Agora vamos fazer a tarefa para pintar o objeto na tela. } public void run() { //precisamos apenas pintar o objeto na posição que a outra //tarefa o deixou no momento this.sair=new Command("Sair". Timer timerRender. class TarefaRenderizacao extends TimerTask { MeuCanvas canvas.midlet. agora precisamos agendá-las. // cria um Timer(Agendador) para cada tarefa this. this.setPositionY(y). TarefaRenderizacao tr. MeuCanvas canvas.setCommandListener(this). public DependenteTempo() { this.canvas=canv.canvas.*.0).setPositionX(x). public class DependenteTempo extends MIDlet implements CommandListener { Command sair.microedition. import javax.canvas).timerMov=new Timer(). Timer timerMov. Isso iremos fazer na classe principal do Aplicativo. Display tela.

Não se esqueça que o nome do arquivo de cada classe deve ser o nome da classe e a extensão de codigos fonte java (.tela.Displayable d) { if(c==this.microedition.*.timerMov.0.java).java e edite os tempo de repetição no schedule() de renderização. onde está 100. this.canvas). // agenda cada tarefa com seu tempo de repetição determinado // nesse caso deixei a movimentação mais freqüente que a renderização this. o quadrado parece estar pulando. agendamos as tarefas no inicio da aplicação (startApp()) e temos um quadrado se movimentando por toda a tela. basta você criar um novo Projeto com o nome de: DependenteTempo e adicionar todas as classes acima no diretório /src da sua aplicação. Se você conseguiu rodar.tela=Display.0.29 { this.setCurrent(this.destroyApp(true). import javax. public class HelloWorld extends MIDlet implements CommandListener { Tutorial J2ME Copyright® . Execute e veja o que aconteceu! O que acabamos de ver é um dos princípios mais importantes para o desenvolvimento de games. você pode perceber que a movimentação do objeto está um pouco truncada.schedule(this. coloque 10 por exemplo.*. this.getDisplay(this).sair) { this. this. .tm. } public void pauseApp() { } public void destroyApp(boolean b) { } public void commandAction(Command c.scheduleAtFixedRate(this.10). Para rodar isso em seu WTK.Codificando A estrutura básica de uma MIDlet dá-se por: /*********** inicio do código **********************/ import javax.tr.lcdui. Agora abra o fonte DependenteTempo.timerRender.2005 .notifyDestroyed(). } } } Pronto.microedition.100).midlet. Agora salve e recompile.

ou uma mensagem sms. { } //método chamado sempre ao início de public void startApp() uma aplicação public void pauseApp() { } //método chamado quando a aplicação é interrompida. por exemplo. e os comandos chamados pelas softKeys } } /******************** Fim do Código ************************/ Com isso podemos ver que a estrutura de uma aplicação é simples. Displayable d) { //método onde será implementado quase toda aplicação. Tutorial J2ME Copyright® . public void destroyApp(boolean condicional) { } //método chamado quando uma aplicação será fechada. ela fica aguardando o Garbage Collector public void commandAction(Command c. quando chega uma ligação.2005 . porém. por ser assim tão simples às vezes restringe a implementação.30 public HelloWorld () { } //metodo construtor da classe.

sair = this.31 Códigos Exemplos Obs: Comentários já feitos não serão repetidos. opcao3.opcao3 this. } public void startApp() { // obter tela do dispositivo this.addCommand(opcao2). 1). Command.opcao4 this.texto.ticker). opcao5. this.setCurrent(this.SCREEN. Command.SCREEN. 2). this. this. 5).addCommand(opcao1). = new Command("Opção 4". Command.getDisplay(this).texto = new TextBox("Commands".texto.ticker = new Ticker("Exemplo de ticker que deve rodar em cima da tela"). public ExemploCommandsAndTicker() { // instanciar TextBox this.texto.setTicker(this.addCommand(opcao5). opcao1. //seta o ticker na tela this.SCREEN.SCREEN. = new Command("Opção 1". 4). } Tutorial J2ME Copyright® . TextBox texto. Ticker ticker. import javax. Command.midlet. ExemploCommandsAndTicker extends MIDlet implements CommandListener Display tela.*.addCommand(opcao3).tela.texto. "Aplicação iniciada". // relacionar Commands com TextBox this.opcao1 this.addCommand(opcao4). this.texto. TextField.microedition. // setar Displayable corrente para a tela this.*. Command sair. opcao4. this.microedition. // registrar TextBox com o CommandListener this.lcdui. 3).texto). 0). //extends de //aplicativo //para que a public class { MIDlet para que o Aplication Manager possa interpretar esse como sendo um aplicativo MIDP e impelementa CommandListener classe tenha que tratar ações de botões .addCommand(sair).ANY).texto. = new Command("Opção 2".2005 .texto. // comandos this.opcao5 do TextBox new Command("Sair". this. opcao2. Sujestão: Copie e cole os códigos em um editor para melhor visualização ExemploCommandsAndTicker import javax. 20.texto.EXIT. = new Command("Opção 3".tela = Display. Command. Command. = new Command("Opção 5".opcao2 this.setCommandListener(this).SCREEN.

32 public void pauseApp() { } public void destroyApp(boolean i) { } //aqui precisamos de um command e um displayable //o displyable será o componente ativo na tela //porque ele extende de Display public void commandAction(Command c..notifyDestroyed().//esse método internamente vai chamar o GC this.sair) { // sair da aplicação this.2005 . //pode-se implementar as outras opcoes aqui //use a imaginacao //ou espere aprender mais algumas coisas e entao acrescente } } Tutorial J2ME Copyright® .setString("Opção 1 selecionada.//notifica sua destruição para a VM } if (c == this.ticker. this.opcao1) { // alterar texto do TextBox this..setString("Opção 1 Selecionada"). } //. Displayable d) { if (c == this.destroyApp(true).").texto.

prox = new Command("Prox". Command. this. "Opcao2".null.erro = new Alert("Erro". TextBox t1.setCommandListener(this).confirmacao = new Alert("Confirmacao". this. um alert modal //que esperará uma intervencao do usuario this.t1 = new TextBox("Result". "Opcao4".1). erro. "Exclusiva".0).Command. //instancia os textbox this.ALARM).TextField. this. this."Alerta de confirmacao". public class ExemploListAndAlert extends MIDlet implements CommandListener { Display tela. "Opcao3"."Alerta de Info".prox1 = new Command("Prox".confirmacao. //instancia todos os alerts //vamos deixar todos eles com null no campo de icone this.info = new Alert("Info".t1.addCommand(this.1).erro."Alerta de Aviso". Tutorial J2ME Copyright® .EXIT.WARNING). aviso.200. List menu. String[] exclusivaElementos = { "Opcao1".null.AlertType.sair).addCommand(this.lcdui.SCREEN. "Multipla" }. "Opcao5".setTimeout(Alert.AlertType. this. "Info". "Opcao2". this.*. String[] multiplaElementos = { "Opcao1".AlertType. confirmacao.t1. multipla. this.midlet. "Opcao4".microedition.setTimeout(5000). //fizemos deste alert.microedition.INFO). "Opcao6" }. Command sair. "Opcao3". "Opcao6" }. "Opcao5". exclusivaElementos.ANY). null). "Erro". exclusiva.null."". info.2005 .setTimeout(4000)."Alerta de Alarme". Alert alarme. this.EXCLUSIVE.alarme = new Alert("Alarme".null."Alerta de Erro".sair = new Command("Sair". //setamos o tempo que ele ficará na tela antes de sumir //lembrando que o tempo decorrido não será exatamente esse.exclusiva.addCommand(sair).null. //instanciar lists //criando a lista exclusiva com o array de elementos criado acima this.prox). this. this. prox1.*.33 ExemploListAndAlert import javax.aviso = new Alert("Aviso".FOREVER).AlertType. import javax. "Aviso".AlertType.exclusiva = new List("Exclusiva".alarme.ERROR).exclusiva.SCREEN. //instancia os comandos this. Choice. prox. public ExemploListAndAlert() { //criamos os arrays de opcoes que irao aparecer nas lists //em aplicações comerciais podem haver lists criadas dinamicamente String[] menuElementos = { "Alarme".Command. //relacionar comandos as textboxes this. "Confirmação".CONFIRMATION). this.

this. //aqui verificamos se foi selecionado um dos Alerts Tutorial J2ME Copyright® .multipla. this.multipla = new List("Multipla".IMPLICIT.setCurrent(this.menu.t1).tela = Display. if (c == this.menu. this. count<6.setString(opcao).exclusiva.t1.tela.setCurrent(this.MULTIPLE. this.prox) { //pega a String do item selecionado para por no textbox opcao = this. Choice.menu = new List("Menu".t1.null).prox1) { //usamos esse laço para verificar quais opções //foram selecionadas para entao apresentalas for(int count=0.setCurrent(this.tela.getSelectedIndex().multipla.menu. this. this.menuElementos.exclusiva. //criando a lista implicita com o array de elementos criado acima //esta lista sera noss menu principal this.setString(opcao).34 //criando a lista multipla com o array de elementos criado acima this. null).isSelected(count)) { //adicionamos as opcoes em uma string só opcao = opcao+this.sair).multipla.Choice.addCommand(this.multipla.notifyDestroyed().sair).addCommand(this.destroyApp(true).menu).prox1). } //aqui comparamos se o comando veio de uma lista //e tambem se a lista era a lista menu if ((c == List.getString(count)+"\n".sair) { this. } public void startApp() { this. } if (c == this. Displayable d) { String opcao = "". this.tela.getDisplay(this).SELECT_COMMAND) && (d == this.menu)) { int selecionado = this. multiplaElementos.2005 . } public void destroyApp(boolean i) { } public void pauseApp() { } public void commandAction(Command c. this.addCommand(this.t1). count++) { if (this. } } this. } if (c == this. this.getSelectedIndex()).setCommandListener(this).getString(this.

multipla.2005 .exclusiva).erro). case 2: this.setCommandListener(this).setCurrent(this. e apos ser mostrado //a tela anterior que é o menu //eh mostrado novamente switch (selecionado) { case 0: this. break.setCurrent(this.confirmacao).multipla).. this.setCurrent(this.exclusiva.info).tela.setCurrent(this. case 5: this. case 1: this. case 3: this.tela. break.tela.setCurrent(this. break.tela.setCommandListener(this). //aqui temos as outras listas.tela. case 4: this. } } } } Tutorial J2ME Copyright® .35 //entao ele eh acionado.alarme).tela. break..setCurrent(this. break.aviso). break.tela. break. case 6: this.setCurrent(this. this.

setCommandListener(this).tela. this. TextField.login = new Command("Login". "".login). this.proximo). TextField.addCommand(this.addCommand(this. 1). resultado.addCommand(this. //adicao dos commands aos aos objetos.getDisplay(this).setCommandListener(this). } //método executado se a MIDlet foir pausada por ela mesma //ou por um evento externo public void pauseApp() { } //método chamado quando a aplicação for encerrada.addCommand(this. this.nome.senha = new TextBox("Senha". this.EXIT. this. this. Command.addCommand(this. "". e são setados como commandListener this.senha. senha.mail. login.nome. Command sair.lcdui.nome = new TextBox("Nome".addCommand(this. import javax. this. 1). Command. //não há necessidade de ser implementada public void destroyApp(boolean condicional) { } Tutorial J2ME Copyright® .addCommand(this. fim.nome).mail = new TextBox("Mail". TextField.36 ExemploTextBox import javax.EMAILADDR).*.mail.proximo = new Command("Proximo". this. proximo.fim = new Command("Fim".senha. this. TextField. Display tela.mail. this. 30.microedition.nome. 1).2005 .ANY). this. public ExemploTextBox() { //construtores dos atributos defindos acima this. Command.fim). 0).sair).PASSWORD).ANY).SCREEN.resultado. this."". this.setCurrent(this. this.microedition.setCommandListener(this). 20. } //método executado ao inicio de Execuçao da MIDlet public void startApp() { this.tela = Display.sair). this.resultado = new TextBox("Resultado".setCommandListener(this).sair = new Command("Sair"."". 20.SCREEN. mail.SCREEN. //construtores dos commands que irao ser adicionados aos objetos this. this. 20.sair).*.senha.resultado.sair).midlet. public class ExemploTextBox extends MIDlet implements CommandListener { TextBox nome. Command. this.

resultado).mail.resultado.tela.login) { this. } if (c == this.tela.proximo) { this.getString()).sair) { this.notifyDestroyed().setCurrent(this. //chama o destrutor } if (c == this. Displayable d) { //definiçao do que será feito quando um command for acionado if (c == this. public void commandAction(Command c. //seta como ativo na tela } if (c == this.setCurrent(this.nome.tela.mail).2005 .senha).setCurrent(this. } } } Tutorial J2ME Copyright® .fim) { //seta a String do objeto resultado pegando o que foi inserido //nos campos anteriores.getString()+" "+this. //notifica que será destruido this.setString(this.37 //método chamado assim que um command for adicionado. this.destroyApp(true). this.

nome).senha).setCommandListener(this). "".sair) { this. TextField nome. Command.*. resultado.tela = Display. Command.38 ExemploForm1 import javax.notifyDestroyed().2005 . proximo. // form de login this.append(this.resultado.login.resultadoMsg = new StringItem("".proximo = new Command("Prox".login.ANY | TextField.resultadoMsg). this. senha.setCurrent(this. Displayable d) { if (c == this.addCommand(this.midlet. 20.addCommand(this.getDisplay(this).login. public class ExemploForm1 extends MIDlet implements CommandListener { Display tela.proximo). //adiciona-se os componentes ao Form Login this. this.sair = new Command("Sair". this.sair). this.resultado.microedition.resultado = new Form("Resultado"). //adiciona-se o componente ao Form Resultado this. TextField. } public void startApp() { this.*.tela. Form login. this. this.destroyApp(true).sair). public ExemploForm1() { // inicializar Commands this.lcdui. Tutorial J2ME Copyright® .login. this.addCommand(this. 0).append(this. // form de resultado this. 1).PASSWORD).senha = new TextField("Senha:".setCommandListener(this).login. Command sair. this.resultado.ANY).""). this. 20.append(this.login). } public void pauseApp() { } public void destroyApp(boolean condicional) { } public void commandAction(Command c.nome = new TextField("Nome:". TextField.microedition. this.SCREEN. this. import javax. this.EXIT. "". StringItem resultadoMsg.login = new Form("Login").

resultadoMsg. this.proximo) { //O Label sempre aparecerá antes do Text não importando //a ordem que vc adicione ele ao componente //faça o teste trocando de ordem as chamdas.getString()).setText(this. this.resultadoMsg. } } } Tutorial J2ME Copyright® .2005 .39 } if (c == this.getString()+" ").setCurrent(this.nome.setLabel(this.tela. this.resultado).senha.

append(this.*. Gauge inter.IMPLICIT. // gauge interativo this. Runnable { Display tela. false. this. 100.40 ExemploGauge import javax.EXIT.gauge1. this.menuCommand). Tutorial J2ME Copyright® .microedition. this.menu. gauge2. Command sairCommand. 0). ItemStateListener. this. 50. this. Command. 0). // menu principal String[] menuElementos = {"Interativo". //preparamos este form para "ouvir" os direcionais do teclado. List. List menu. //setamos o label inicial do gauge //true para torna-lo interativo //50 é o numero de toques qeu ele necessitará para ser completado //0 para indicar seu inicio. this. this.addCommand(this. import javax. /** * neste exemplo vamos implementar mais duas interfaces * o ItemStateListener vai nos ajudar a reconhecer as Setas direcionais * do teclado do dispositivo.sairCommand). 1). **/ public class ExemploGauge extends MIDlet implements CommandListener.lcdui. this. // gauge nao-interativo this. ninter.inter = new Gauge("0 %".menu = new List("Menu Principal". this. //somente do false indica qeu este gauge esta somente //sobre controle do programa this.setCommandListener(this).SCREEN. public ExemploGauge() { // inicializar Commands this. Command.addCommand(this.menuCommand = new Command("Menu".2005 .append(this. * e a interface Runnable desempenha o papel de uma Thread * onde poderiamos ter usado uma classe extra extendendo de Thread * no entanto preferimos simplificar a implementação.midlet.gauge1. menuElementos. this.gauge1.*. true. Thread minhaThread. this. //mesma coisa que o gauge anterior.gauge2. menuCommand. "Não Interativo"}.gauge2 = new Form("Não Interativo"). * usamos o recurso de Thread por que não haveria possibilidade * de incrementar nosso gauge. * O processamente paralelo será usado afim de mostrar o * movimento do gauge nao interativo.gauge1. Form gauge1. null).ninter = new Gauge("0%". e mostra-lo na tela * na mesma linha de execuçao.microedition.menu.inter).setItemStateListener(this). //declararemos um for para cada gauge. 0).gauge1 = new Form("Interativo").ninter).sairCommand = new Command("Sair".setCommandListener(this).sairCommand).addCommand(this.gauge1.

notifyDestroyed().menu) { //se for o primeiro item que é o gauge interativo //ele apresenta o gauge e espera por comandos.tela = Display.gauge2.menuCommand) { this. } public void pauseApp() { } public void destroyApp(boolean condicional) { } public void commandAction(Command c.addCommand(this.gauge1). this. this.menu).getDisplay(this). minhaThread. } if (c == this.inter) { Tutorial J2ME Copyright® .2005 .tela.sairCommand) { this.sairCommand).setCurrent(this.start().41 this.setCurrent(this.setCurrent(this.tela.setCommandListener(this).menu).gauge2).tela.getSelectedIndex() == 0) { this. } //verifica qual item da lista do menu principal foi selecionado if (c == List.menuCommand).destroyApp(true).menu.minhaThread = new Thread(this). } public void startApp() { this.addCommand(this.menu.setCurrent(this. this. } } } /** * controle do gauge interativo conforme o valor vai mudando ele * vai aprensentando na tela o valor correspondente * e como setamos ele para que fosse somente ateh 50 * multiplicamos por 2 os valores para supostamente * chegar a 100% **/ public void itemStateChanged(Item i) { if (i == this. } //se for o gauge nao interativo. if (this. ele inicial nossa "thread" //a qual controlará nosso gauge fazendo-o aumentar até onde determinarmos if (this.SELECT_COMMAND && d == this.gauge2. Displayable d) { if (c == this. this.gauge2.tela. this.getSelectedIndex() == 1) { this.

2005 . * por curiosidade.inter.42 this.sleep(30). Tutorial J2ME Copyright® .setLabel(" } } //controle do gauge Nao interativo //execução da nossa Thread (Runnable) public void run() { for (int cont = 1. **/ try { Thread. cont <= 100.ninter. cont++) { /** * usamos este try-catch porque precisamos usar o sleep * para dar uma pausa pequena para melhor vizualizacao * do incremento. } catch (Exception e) { } this. } } } "+(this.ninter.setValue(cont). auemnte e dimunua o valor do sleep * lembre-se o valor é dado em milisegundos.getValue()*2)+"%"). this.inter.setLabel(" "+cont+"%").

} public void pauseApp() { } public void destroyApp(boolean bool) { } public void commandAction(Command c. javax.microedition.*.EXIT. } public void startApp() { this.setCommandListener(this).imageForm = new Form(""). this.imageForm). //ImageItem onde a foto que virá do servidor será salva. //string com a url para a imagem //colocamos a url diretamente aqui somente para exemplo //uma idéia seria vc deixar o usuario setar esse link //em um textbox ou algo do genero.sairCommand) Tutorial J2ME Copyright® .sairCommand = new Command("Sair"."").addCommand(this. this.0. //imageItem onde será posta a imagem que vier do server //inicializamos ela com zero.buscarCommand = new Command("Buscar". this.*.buscarCommand).br/suafoto. //form onde será exibida a imagem Form imageForm.getDisplay(this). public ConnectionImage() { this. public class ConnectionImage extends MIDlet implements CommandListener { Display tela.midlet.png".null.imageForm. this.microedition. 0).seusite. this. Command. //comandos Command buscarCommand. Command.foto = new ImageItem("foto".tela. String url = "http://www. ImageItem foto. Displayable d) { if (c == this.imageForm. this.addCommand(this.43 ExemploConnectionImage import import import import javax.io.com.microedition.imageForm.SCREEN. javax. sairCommand.2005 .*. //o qual poderia ser feito na hora de postar.tela = Display.*. java.sairCommand).io.setCurrent(this. this. 1).lcdui.

size(). o qual nao nos garante nada. // Display the form with the image this.readFully(imageData). while ((ch = iStrm.getLength(). } try { Image im.open(url).destroyApp(true). //chama o método que busca a imagem im = getImage(this. this.write(ch). this. * embora a conexao http tambem nao seja muito confiavel.foto). i < imageForm.read()) != -1) bStrm. imageForm.44 { this. **/ ContentConnection connection = (ContentConnection) Connector. i++) imageForm.tela. try { byte imageData[].notifyDestroyed(). Image im = null. }catch(Exception e) { } } } /** * Abre uma conexão http e baixa um arquivo png * em um array de bytes **/ private Image getImage(String url) throws IOException { /** * usamos aqui ao invés de httpconnection * a conexao padrao.append(this.url).2005 . if (length != -1) { imageData = new byte[length]. int ch.setCurrent(imageForm).foto. } else if(c == buscarCommand) { //se já houver um ImageItem no form //ele irá deleta-lo antes de jogar uma nova imagem if (imageForm.size() > 0){ for (int i = 0.toByteArray().openDataInputStream().delete(i). // Le um png em um array iStrm.setImage(im). } else //se o tamanho não está disponível { ByteArrayOutputStream bStrm = new ByteArrayOutputStream(). imageData = bStrm. int length = (int) connection. DataInputStream iStrm = connection. Tutorial J2ME Copyright® .

length).createImage(imageData.close().2005 . } //Cria a imagem de um array de bytes im = Image. imageData.45 bStrm. } return (im == null ? null : im). } finally { // Clean up if (iStrm != null) iStrm. if (connection != null) connection.close(). 0.close(). } } Tutorial J2ME Copyright® .

List. As paginas podem tanto ser .lcdui.2005 .sair) { this. String url = "www. voltar.*. this.io. visto que nao é este nosso objetivo.io. this. Tutorial J2ME Copyright® .registros. Command sair.addCommand(this.listar).EXIT.microedition.Command.registros).microedition. public ExemploConnect() { this.tela = Display.result = new List("Dados Cliente". result. Isto é só um exemplo.setCommandListener(this).result.List.46 ExemploHttpConnection /** Este exemplo faz uma conexao http com um server.seusite. **/ import import import import javax. this. List registros. } public void pauseApp() { } public void destroyApp(boolean b) { } public void commandAction(Command c. javax.jsp". this.*.registros. this.setCommandListener(this).setCurrent(this. java. Command. this.*. a parte ServerSide fica de sua responsabilidade. da pessoa. 0).IMPLICIT).notifyDestroyed(). } public void startApp() { this. o qual retorna um lista de usuarios dos quais nos podemos entao fazer uma consulta apenas selecionando ele da lista e a outra url nos retornará os dados.midlet. como Servlets.SCREEN.sair = new Command("Sair".registros.voltar).addCommand(this.br/suaPagina.IMPLICIT).getDisplay(this). this.registros = new List("Clientes".voltar = new Command("Voltar".listar = new Command("Listar".jsp.com.Command.destroyApp(true).microedition.result.addCommand(this. this. this.sair). listar. 1).tela. Displayable d) { if(c == this.SCREEN. public class ExemploConnect extends MIDlet implements CommandListener { Display tela.*. this. 0). this. javax.

conecta(this. int lido = is. this.read().open(this. } } public void conecta(List lista) { try { //estabelecemos uma conexao http com a url.setLength(0).null).com. i < tamanho. this.openInputStream().jsp?cod=".voltar) { int tamanho = this. String urlBusca = "www. } this.append(sb. } //quando chamar o voltar limpa a lista para evitar //que sejam readicionados os mesmo itens na proxima conexao if(c == this.tela. StringBuffer sb = new StringBuffer().registros).2005 .getResponseCode().getSelectedIndex()). HttpConnection con = (HttpConnection) Connector.delete(i).substring(0.result.tela. for(int i= 0. //como a conexao foi http.SELECT_COMMAND) { String linha = this.conecta(result). sb.br/BuscaCodigo. if(b1 == (byte)'\n') { lista. i++) { this. int status = -1.registros. if(c == this.seusite. String cod = linha.url = urlBusca+cod. //passamos a lista como parametro //pois é onde sera montado o resultado da busca this.HTTP_OK) { InputStream is = con.setCurrent(this.linha.47 } //chama a função que faz a conexao com a pagina. status = con.indexOf("-")).setCurrent(this.registros). //como podemos perceber abaixo //é lido byte a byte do servidor. } else { Tutorial J2ME Copyright® .result).registros. } //verifica o item escolhido e entao pega o codigo //e o junta com a url para fazer a busca no servidor if(c == List.size().toString().listar) { this. é verificado o status da conexao if(status == HttpConnection.url). while (lido != -1) { byte b1 = (byte)lido.getString (this.result.

null).2005 .append((char)b1). else { lista. } } //se nao conseguir estabelecer conexao.append("Nenhum Registro Encontrado!".48 sb. } lido = is. } } catch (IOException io1) { } } } Tutorial J2ME Copyright® .read(). //colocamos esta mensagem como padrao.

sair) { Tutorial J2ME Copyright® . // prepara o canvas para "escutar" os comandos this. // para desenhar na tela precisamos da Classe Canvas // como nossa classe principal não pode extender a classe Canvas // criaremos uma outra Classe que extenda de Canvas NossaCanvas canvas.lcdui.sair).canvas). } public void pauseApp() { // não precisa executar nada se não quiser } public void destroyApp(boolean b) { // não precisa executar nada se não quiser } // metodo abstrato da interface CommandListener. import javax. this. * Canvas é o uso de graficos em nivel baixo.Command. } public void startApp() { //define a tela para o objeto NossoCanvas que vai desenhar na tela this.tela. caso vc queira interagir com a aplicação! public class ExemploCanvas extends MIDlet implements CommandListener { Display tela.canvas=new NossaCanvas().. // Toda a aplicacao tem que extender de MIDlet.getDisplay(this).EXIT. //adiciona o comando sair ao canvas this.microedition.setCurrent(this.microedition.canvas.0).2005 .*. e implementar //a interface CommandListener.sair=new Command("Sair".setCommandListener(this). **/ import javax. // inicia o NossoCanvas this..tela=Display. if(c==this.49 ExemploCanvas /** * Vamos construir um exemplo do uso do Canvas em J2ME. é ativado quando algum comando é acionado public void commandAction(Command c. //classe criada mais a baixo public ExemploCanvas() { this.canvas. * Vamos a ele.*.addCommand(this.midlet. Command sair. Displayable d) { // reconhece que o comando foi o sair e executa.

e onde as coordenadas devem ser consideradas na string g.drawRect(5.7. //cria-se uma variavel String porque o método drawString() nao aceita o uso de lala diretamente no método.notifyDestroyed().96. //cria um retangulo ja pintado com a cor definida g.2005 . //define uma cor RGB g.setColor(255.0. // define o texto as coordenadas.5. this. //existe também uma sobrecarga para este método com cor de 8 bits g.TOP). } } } //classe criada extendendo de Canvas class NossaCanvas extends Canvas { public NossaCanvas() { } // metodo abstrato de Canvas que pinta na tela //ele é acionado na criacao do objeto e quando usa-se o metodo repaint() public void paint(Graphics g) { g.7.Graphics.setColor(192). String teste="NoSSo Canvas".255).59).64). } } Tutorial J2ME Copyright® . //desenha um retangulo sem preenchimento g.255.destroyApp(true).drawString(teste.setColor(128).88.LEFT|Graphics.fillRect(0.50 this.

Leandro Batista de .51 Referências Bibliográficas Keogh. Jonathan The Complete Reference Wireless Java Editora Osborne Editora Apress Developing with J2ME Almeida. James .Material de Apoio Tutorial J2ME Copyright® .J2ME Knudsen.2005 .

ou disponibilização sem prévia autorização.2005 .52 Copyright Não é autorizado o uso desta apostila indevidamente sem autorização. entenda-se reprodução para fins lucrativos. Tutorial J2ME Copyright® .

The unregistered version of Win2PDF is for evaluation or non-commercial use only. .daneprairie.com.This document was created with Win2PDF available at http://www.

Sign up to vote on this title
UsefulNot useful