Esse artigo faz parte da revista WebMobile edição 1. Clique aqui para ler todos os artigos desta edição

wm1_capa.JPG

Introdução ao J2ME

Por Juliano Carniel e Clóvis Teixeira

Todos já ouviram falar da tecnologia Java. E com a evolução dos aparelhos celulares, dos PDA’s e das tecnologias de comunicação, Java também ganhou importância no mundo dos aparelhos móveis, disponibilizando uma plataforma segura e muito bem fundamentada para programadores e fabricantes de celulares.

A tecnologia Java subdivide-se em três grandes partes: J2EE, J2SE e J2ME. O Java 2 Micro Edition (J2ME) é uma API Java voltada para microaplicativos que rodam em microdispositivos assim como os celulares e PDA’s. É sobre essa tecnologia que este artigo tratará, buscando demonstrar de uma forma prática o desenvolvimento de aplicações J2ME, desde a instalação do ambiente de desenvolvimento até a construção de uma aplicação simples, porém bem mais “sofisticada” do que um simples HelloWorld.

Introdução ao J2ME

O J2ME, assim como quase toda tecnologia Java, é regulamentada pelo JCP (Java Comunity Process). Entretanto, existem várias empresas de grande porte por trás do J2ME, como: Nokia, Motorola, IBM, Intel, Sony, Siemens.

Java 2 Micro Edition (J2ME) é subdividido em duas importantes camadas: Configuration e Profile. Além dessas, existem ainda as API’s opcionais, algumas disponibilizadas por fabricantes, ou mesmo por versões mais novas da tecnologia.

As Configurations provêem os serviços mais básicos para que as aplicações possam rodar, tais como: sistemas de comunicação, a segurança interna da Virtual Machine e o acoplamento com o dispositivo. Existem dois tipos de Configurations:

·         a CDC (Connected Device Configuration), que é usada em dispositivos um pouco maiores como: set-top boxes (aparelhos de TV por assinatura) e sistemas de telemetria de carros, os quais possuem um processamento razoável e uma memória um pouco maior.

·         a CLDC (Conected Limited Device Configuration), que é usada por dispositivos com pouca memória e um processador relativamente fraco, como é o caso dos celulares, PDA’s e Pagers.

 

Já os Profiles provêem uma série de API’s padrões que combinados com uma configuration, no nosso caso o CLDC, provêem um serviço completo para que as aplicações possam ser executadas.

Existem vários tipos de Profiles, contudo gostaria de destacar dois deles: (1) o MIDP (Mobile Information Device Profile) e (2) o PDAP (Personal Digital Assistant Profile) usado para PDA’s. Com relação ao MIDP, existem atualmente duas versões: a 1.0 e a 2.0. A versão do MIDP1.0 está integrada praticamente em todos os celulares atuais. Quanto ao MIDP2.0, existem atualmente vários celulares no mundo com essa tecnologia, que só tende a ganhar espaço, pois sua compatibilidade com a versão 1.0 é total. Entretanto, no Brasil existem apenas alguns que começaram a ser inseridos no mercado a partir do início de 2004.

As aplicações em J2ME, principalmente para celulares (que são as mais produzidas), costumam ser chamadas de MIDlet’s pelo fato delas obrigatoriamente sempre herdarem (extends) de MIDlet (como veremos a seguir). O MIDP exige dispositivos com os seguintes requisitos mínimos:

·         Mínimo de 160kB de memória não-volátil para Java;

·         Um processador de 16 bits ou 32 bits com um clock de no mínimo 16MHz;

·         32KB de memória volátil para tempo de execução;

·         Pelo menos 192KB livres para Java;

·         8KB de memória não-volátil para armazenamento de dados;

·         Uma tela de pelo menos 96x54 pixels;

·         Capacidade de entrada de dados seja por teclado (do celular), teclado externo ou mesmo touch-screen;

·         Possibilidade de enviar e receber dados em conexão possivelmente intermitente e banda reduzida.

 

Os aparelhos que suportam J2ME trabalham basicamente com dois tipos de arquivos, os com extensão jad (Java Application Descriptor) e os de extensão jar (Java Archive). O arquivo .jad é um arquivo de descrição do aplicativo e dentro dele há algumas informações referentes ao fabricante, versão, link pra o .jar, entre outras. Já o arquivo .jar é o aplicativo propriamente dito, todas as classes compiladas estão lá dentro, bem como as imagens usadas nas aplicações. O arquivo .jad é necessário apenas para fazer download do aplicativo direto pelo celular via web. Se for usado algum outro meio de transferência de aplicativos, em geral, ele não será exigido.

 

Componentes do J2ME

Todos os celulares, além do seu teclado numérico (ou qualquer que seja o método de entrada de dados), possuem teclas especiais chamadas de SoftKeys ou SoftButtons que se adaptam às diversas aplicações. A essas teclas são associados os commands que interagirão com o usuário. Estes commands são definidos pelo programador, embora ele não saiba exatamente onde estarão localizados na interface com o usuário. Somente em tempo de execução o programa saberá onde alojar cada command, conforme a característica (CommandType) definida para ele. Algumas dessas características podem ser: ok, back, exit, screen, etc. Esses commands devem ser adicionados a um objeto que deve herdar de Displayable.

Conforme pode ser visto na Figura 1, existem duas classes que herdam diretamente de Displayable: Canvas e Screen. Canvas é usada para se ter uma referência de mais baixo nível à tela, ou seja, manipularmos diretamente os gráficos apresentados. Já a classe Screen possui várias subclasses como Alert, List, TextBox e Form. Dessas, a classe Form é usada como container para que se possa adicionar outros componentes, que são chamados de Itens, como: ChoiceGroup, ImageItem, Gauge, TextField, StringItem, TextField. Combinando-se esses itens podemos obter uma interface amigável, entretanto, é importante precaver-se contra o uso excessivo de itens adicionados a um mesmo Form, por questões estéticas e de facilidades de uso.

 

image002.gif


Figura 1. Herança de classes.

 


Gostaria de destacar também que o J2ME, assim como o resto da tecnologia Java, possui um GarbageCollector. Porém, esse método não é executado de forma automática, é preciso, dependendo da aplicação, chamá-lo para a liberação de memória.

Instalando e configurando o ambiente

Neste artigo usaremos a IDE NetBeans que pode ser baixada no site http://www.netbeans.org e o módulo do NetBeans chamado NetBeans Mobility que também pode ser baixado no próprio site do NetBeans. Você irá instalá-lo normalmente como qualquer programa.

A partir de agora veremos um pequeno tutorial sobre importação de projetos do Wireless Toolkit para o NetBeans e a criação de um novo projeto nesta IDE. O Wireless Toolkit (WTK) é uma plataforma gratuita para a execução de aplicativos em J2ME (já vem com alguns emuladores) que pode ser encontrada para download no próprio site da Sun. O WTK não contém um editor próprio para os programas, apenas requer que você adicione a ele o projeto para poder rodar. O NetBeans, plataforma adotada para esse tutorial com o seu plugin NetBeans Mobility, já contém o WTK integrado a ele.

Importando um projeto do Wireless Toolkit

Com o NetBeans aberto, vá em File ->New Project. Na tela “Choose Project” iremos escolher a Categoria “Mobile”. O que nos dará as opções mostradas na Figura 2.

 

image003.jpg

(Clique aqui para ampliar a imagem)

Figura 2. Tela de novo projeto de Mobile.

 

Caso você já tenha o WTK instalado e com aplicações “desenvolvidas” nele, você poderá migrá-las para o NetBeans. Para isso escolhemos a Opção: “Import Wireless Toolkit Project” e apertamos “Next”. Feito isto é apresentada a tela para selecionar o projeto desenvolvido no WTK. Em seguida haverá uma tela para colocarmos o caminho de diretórios de onde o seu WTK (Wireless Toolkit) encontra-se. Colocado o caminho do diretório, aparecerá uma lista de todos os projetos que há no WTK especificado, então basta selecionarmos o projeto desejado e apertar “Next”, como podemos ver na Figura 3.

 

image005.jpg

(Clique aqui para ampliar a imagem)

Figura 3. Tela de especificação da localização do WTK.

 

Feito isto, teremos de escolher o nome do projeto e o endereço onde queremos que ele fique. Na mesma tela temos uma opção “Set as Main Project” que se selecionado tornará o projeto importado como o projeto principal do NetBeans (ver Figura 4).

 

image007.jpg

(Clique aqui para ampliar a imagem)

Figura 4. Especificação do nome e localização do Projeto para o NetBeans.

 

Na próxima tela (Figura 5), escolheremos a plataforma de desenvolvimento, que por padrão é J2ME Wireless Toolkit. Após esta seleção, escolhemos ainda em que tipo de emulador queremos que nossa aplicação seja executada. Na configuração do dispositivo, escolhemos se ele vai emular CLDC1.0 ou CLDC1.1 (CLDC1.0 é o padrão de mercado atual). E por fim, o Profile que poderá ser MIDP1.0 ou MIDP2.0 (como já vimos o MIDP1.0 existe em maior número). Apertamos “Finish” e temos o projeto criado.

 

image009.jpg

(Clique aqui para ampliar a imagem)

Figura 5. Especificação da Plataforma a ser utilizada para o projeto.

 

Vale lembrar ainda, que ele não usa o projeto que estava sendo utilizado pelo desenvolvedor com o WTK, ele copia os arquivos do projeto para o diretório que escolhemos. Logo, o que for alterado no NetBeans não será alterado no seu projeto no WTK.

Criando um novo projeto

Para criarmos um novo projeto, repita os mesmos passos que fizemos no tópico anterior, porém agora escolha “Mobile Application” (Figura 2) e aperte “Next”. Isso nos leva a uma nova tela chamada “Project Name and Location”. Nesta nova tela vamos escolher o nome do projeto e sua localização em disco (Figura 6). Esta tela nos dará ainda mais duas opções:

·         Set as Main Project: o que faz com que esse projeto seja tido como o principal pelo NetBeans.

·         Create Hello MIDlet: essa opção faz com que o NetBeans crie pra você a classe principal (MIDlet) pronta para ser executada no emulador. Nesta classe já são implementados todos os métodos que são necessários para um MIDlet rodar. Se você nunca programou em J2ME essa opção é recomendada.

 

image011.jpg

(Clique aqui para ampliar a imagem)

Figura 6. Especificação do nome e localização do projeto.

 

Após ter selecionado as opções aperte “Next”. Uma nova tela é mostrada: “Plataform Selection”. Nesta tela, como vimos na importação de projetos (Figura 5), temos que escolher a plataforma de desenvolvimento J2ME. Primeiro escolhemos qual plataforma de emulação trabalhar, que por padrão é o WTK. Escolheremos então o aparelho emulador. Depois escolha a configuração do dispositivo: CLDC1.0 ou CLDC1.1, e por fim o profile: MIDP1.0 ou MIDP2.0. Apertamos “Finish” e temos o projeto criado.

Executando o seu projeto no emulador

Para executar seu projeto, basta você clicar no botão Run Main Project na barra de ferramentas, ou apertar a tecla F6 (isso se o projeto tiver sido definido como “Main Project”). Se ele não for, você pode torná-lo “Main Project”, bastando para isso clicar com o botão direito do mouse no nome do projeto na janela “Projects” e escolher a opção “Set Main Project” conforme ilustrado na Figura 7.

 

image013.jpg

Figura 7. Selecionando nosso projeto como Principal.

 

Você também pode executá-lo clicando com o botão direito do mouse sobre o nome do projeto e escolhendo “Run Project”. Esta última forma independe se o projeto é “Main Project“ ou não.

Criando o projeto ExemploWebMobile

Depois de termos visto como criar projetos e como utilizar nossa IDE, vamos agora aprender como programar um pouco de J2ME. Neste artigo iremos desenvolver uma aplicação que vai um pouco além de um simples Hello World, visto que isso a própria IDE já cria. Nossa aplicação abordará a estruturação de uma aplicação em J2ME, mostrando os principais componentes que podem ser utilizados, e também alguns fluxos de telas.

Inicialmente iremos criar um novo projeto, porém dessa vez, um projeto vazio. Para isso, seguiremos os passos descritos no tópico “Criando um novo projeto”, mas dessa vez não iremos selecionar a opção “Create Hello MIDlet” na tela “Project Name and Location” (Figura 6).

Feito isto, nosso segundo passo é criar uma classe que herda de MIDlet (extends MIDlet). Para isso, clicamos com o botão da direita do mouse no nome do projeto (ExemploWebMobile), escolhemos a opção New-> MIDlet. Aparecerá então uma tela onde iremos escolher o nome da MIDlet e o nome da classe MIDlet conforme Figura 8. Chamaremos essa MIDlet de “ExemploWebMobile” assim como o nome da classe principal que irá herdar de MIDlet. Podemos ainda especificar o ícone para a aplicação, bastando para isso que você tenha uma figura de um tamanho pequeno (16x16, podendo variar) dentro do diretório de sua aplicação.

image015.jpg

(Clique aqui para ampliar a imagem)

Figura 8. Criando uma nova MIDlet.

 

Podemos também neste passo atribuir essa MIDlet a um Package. Caso não usássemos Package, o próprio NetBeans adicionaria essa classe a um default Package. Em nosso caso, criaremos a MIDlet e todas as outras classes dentro de um Package chamado “br.com.webmobile”. Apertamos “Finish” e temos uma classe básica herdando de MIDlet e alocada  dentro do Package criado.

Tendo criado o projeto, agora vamos realmente ao que interessa: a implementação das classes de exemplo para que possamos conhecer mais de J2ME. Dê uma olhada na Listagem 1. Ela apresenta nosso arquivo ExemploWebMobile.java. Note que o NetBeans já adicionou os dois imports necessários para que possamos fazer nossa aplicação. No primeiro pacote, javax.microedition.midlet.*, temos a super classe da qual herdamos e no segundo, import javax.microedition.lcdui.*, temos todos os componentes gráficos que poderemos utilizar em nossas aplicações.

Essa nossa classe herda (extends) de MIDlet, o que a torna o aplicativo principal (válido) para a Virtual Machine de J2ME. Como não selecionamos a opção HelloMIDlet na criação do projeto, a nossa classe principal não vem com a interface de Command, a CommandListener. Então, mãos à obra...

A primeira coisa que devemos fazer é implementar a interface CommandListener na nossa classe MIDlet. Para isso colocamos do lado de extends MIDlet, a declaração implements CommandListener. Devemos também implementar o método commandAction(Command c,Displayable d) para tratar os eventos dos Commands como pode ser visto na linha 83 da Listagem 1.

Entretanto, antes de começarmos a falar do nosso exemplo, vamos aprender o que são os três métodos abstratos que devem estar presentes nas classes que herdam de MIDlet:

·         public void startApp() (linha 57 da Listagem 1): é o método que será chamado no início de execução do aplicativo. Ele será chamado logo depois do construtor da classe. Geralmente aqui é definido o componente que será mostrado na tela.

·         public void pauseApp() (linha 72 da Listagem 1): é o método que será chamado quando houver uma interrupção na execução do aplicativo por parte do sistema operacional do aparelho, por exemplo, o recebimento de uma ligação, mensagem de bateria fraca, etc. Aqui deve-se criar um meio de congelar(pause) a aplicação para que ela possa ser recuperada corretamente depois da interrupção.

·         public void destroyApp(boolean b) (linha 79 da Listagem 1): é o método chamado quando o aplicativo é fechado. Aqui se podem colocar códigos para persistir alguma informação que você queira recuperar nas próximas vezes que abrir o aplicativo.

 

É importante lembrar que esses três métodos devem estar presentes em qualquer classe que herde de MIDlet. Porém, não precisam conter código dentro deles, a não ser o startApp, que é onde chamamos um componente Displayable para a tela.

Sabendo disso, podemos prosseguir para o nosso exemplo. A tela inicial do nosso exemplo é uma List, com duas opções, Itens e Alerts, onde estaremos mostrando exemplos de uso de Itens e de Alerts respectivamente. Para criarmos essa tela inicial vamos precisar de pelo menos um Command, que é o comando para sairmos da aplicação. Podemos ver no código da Listagem 1 que declaramos um Command cmdSair (linha 15), e no construtor inicializamos esse Command (linha 28).

Criamos então um array de string com as opções e passamos como parâmetro para o construtor da List (linha 39). Criada a List, adicionamos os Commands a ela e definimos que a List capture eventos de Command com o método setCommandListener (linha 49). Feito isso, terminamos o construtor da classe. Agora vamos definir a nossa List como a tela inicial. Fazemos isso no método startApp. Para esse nosso exemplo não iremos colocar código nos métodos pauseApp e destroyApp, já citados acima.

Agora vamos direto ao método da interface CommandListener, o commandAction (linha 84). Nele nós fazemos os testes para verificar que command foi ativado, para realizarmos o procedimento desejado para cada opção. A seguir (linha 123), criaremos um método que possa ser acessado por todas as classes do aplicativo a fim de definir o componente Displayable a ser mostrado na tela. Com isso terminamos a classe principal.

 

1: /**

2: * Classe que herda de MIDlet, o que a torna aplicação J2ME,

3: * e classe principal para a aplicação.

4: * Implementa CommandListener que define que ela controlará ações dos commands

5: */

6:

7:package br.com.webmobile;

8:

9:import javax.microedition.midlet.*;

10:import javax.microedition.lcdui.*;

11:

12:public class ExemploWebMobile extends MIDlet implements CommandListener

12:{

14:    private Display display; // Irá receber uma referencia ao display do aparelho

15:    private Command cmdSair; // Comando para sair da Applicação

16:    private List list; //lista que será usada como menu principal

17:   

18:   

19:    public ExemploWebMobile()

20:    {

21:          /**

22:          * O texto "Sair" é o label do Comando.

23:          * A opção EXIT foi usada para que a VM possa colocar o command onde

24:          * normalmente aparece o botão de EXIT das aplicações nativas do celular

25:          * fazendo com que isso torne a aplicação padrão com qualquer celular.

26:          * O terceiro parâmetro é a ordem dos Commands caso haja mais de um do mesmo tipo.

27:          */

28:          this.cmdSair = new Command("Sair", Command.EXIT, 0);

29:   

30:          String itens[] = {"Itens", "Alerts"} ; //lista de itens do menu(List)

31:          /**

32:          * A opção IMPLICIT foi definida pois assim ela age

33:          * como se fosse um command. As opções da lista devem ser escolhidas

34:          * pela tecla de SELECT do celular

35:          * A opção de null foi definida por que não iremos usar imagens para os

36:          * itens da lista, caso fosse usado seria necessário um array de Image,

37:          * uma Image para cada opção.

38:          */

39:          this.list = new List("Menu", List.IMPLICIT, itens, null);

40:   

41:          //adiciona-se o command Sair a list

42:          this.list.addCommand(this.cmdSair);

43:   

44:          /**

45:          * seta a List como Listener de commands e define-se que

46:          * a própria classe tratará dos eventos de command, pois ela

47:          * que implementa a Interface CommandListener

48:          */

49:          this.list.setCommandListener(this);

50:

51:  ` }

52:     

53:    /**

54:     * Método herdado de MIDlet o qual é executado

55:     * logo após o construtor da aplicação

56:     */

57:    public void startApp()

58:    {

59:          // coloca-se a instancia de Display da VM em um objeto

60:     //Display para podermos manipulá-lo.

61:          this.display = Display.getDisplay(this);

62:          // definimos a List como a tela a ser mostrada

63:          this.display.setCurrent(this.list);

64:    }

65:   

66:    /**

67:     * Método usado quando a aplicação entra em mode de pausa,

68:     * seja por uma ligação recebida, ou qualquer outra ação do celular

69:     * normalmente guarda-se o estado atual da aplicação para que quando

70:     * ela volte esteja com o estado igual ao anterior ao pause

71:     */

72:    public void pauseApp()

73:    { 

74:    }

75:   

76:    /**

77:     * Método usado para finalizar a aplicação

78:     */

79:    public void destroyApp(boolean unconditional)

80:    { 

81:    }

82:   

83:    public void commandAction(Command c, Displayable d)

84:    {

85:            //quando o command selecionado for o Sair 

86:            if(c == this.cmdSair)

87:            {

88:         this.destroyApp(true);

89:         //notifica a VM que a aplicação foi destruida

90:         this.notifyDestroyed();

91:            }

92:   

93:            /**

94:       * Verifica qual dos itens da lista foi selecionado, e se foi através

95:       * da tecla de Select do celular.

96:       * Pode-se usar o parâmetro Displayable para verificar se foi o command

97:       * de determinada tela que foi selecionado, porém não precisa ser usado

98:       * caso você tenha certeza que determinado command é único

99:       * e pertence somente àquela tela

100:      */

101:    

102:           if(c == List.SELECT_COMMAND && d == this.list)

103:           {

104:        switch(this.list.getSelectedIndex())

105:        {

106:          // cada case representa a posição da opção dentro do List, começando com 0

107:          case 0:

108:              new ExemploFormItens(this);

109:          break;

110:       

111:          case 1:

112:              new ExemploListAlerts(this);

113:          break;

114:        }

115:           }

116:   }

117:   

118:    /**

119:     * Método que será usado pelas outras classes para se definir

120:     * objeto que será mostrado na tela.

121:     * Se for passado null, a tela principal será novamente mostrada

122:     */

123:    public void setDisplayable(Displayable d)

124:    {

125:         if(d == null)

126:          this.display.setCurrent(this.list);

127:         else

128:          this.display.setCurrent(d);

129:    }

130:}

Listagem 1. Código da classe ExemploWebMobile.

 

 

As classes que iremos implementar agora será a próxima a ser utilizada pelo sistema durante a utilização da aplicação. Ou seja, implementaremos agora a classe ExemploFormItens, que se refere a primeira opção da List implementada na Listagem 1, conforme demonstrado na Figura 9.

 

image017.jpg

Figura 9. Aplicativo rodando no emulador com a classe ExemploWebMobile.

 

A classe ExemploFormItens (apresentada na Listagem 2) é inicializada dentro do método commandAction da classe principal (Listagem 1, linha 108). Nesta classe são usados vários componentes UI (User Interface) do J2ME, mais especificamente Form, StringItem, TextField, DateField e ChoiceGroup.

Os componentes criados nesta classe são adicionados a um formulário (Listagem 2, linhas 54-57) o qual será mostrado na tela. Temos comandos para voltar e, para gravar o que foi selecionado e preenchido. Não fizemos a validação dos dados para deixarmos a aplicação mais simples. Acompanhe no código da Listagem 2 para saber como são inicializados os componentes e como são adicionados ao formulário. O resultado da Listagem 2 é demonstrado na Figura 10.

 

1: package br.com.webmobile;

2:

3: import javax.microedition.lcdui.*;

4:

5: public class ExemploFormItens implements CommandListener

6: {

7:    private ExemploWebMobile main; //referencia a MIDlet principal

8:    private Command cmdVoltar;

9:    private Command cmdGravar;

10:    private Form form; //form que será usado como container para os Itens

11:    private StringItem itString; //StringItem (label:text) simples string de texto

12:    public TextField itTextField; //análogo ao JTextField do swing

13:    public DateField itDtField; //como um TextField porém abre um calendário

14:    public ChoiceGroup itChGrp; //lista que pode ser adicionada a um container

15:                                //pode ser como checkbox ou radio

16:

17:    public ExemploFormItens(ExemploWebMobile princ)

18:    {

19:       this.main = princ;

10: 

20:       this.cmdVoltar = new Command("Voltar", Command.BACK, 0);

21:       this.cmdGravar = new Command("Gravar", Command.OK, 0);

22: 

23:       // o Form possui vários construtores com parâmetros diferentes, no caso

24:       //abaixo

25:       // passamos somente o Título do Form.

26:       this.form = new Form("Form com Itens");

27: 

28:      // StringItem é basicamente uma String no formato label:valor

29:      this.itString = new StringItem("Aplicativo","WebMobile");

30: 

31:      // Caixa de texto que vem com label embutido.

32:      // o terceiro parâmetro é o tamanho maximo do campo

33:      // o quarto é o tipo do campo, uma esécie de máscara.

34:      this.itTextField = new TextField("Telefone","",20,TextField.PHONENUMBER);

35: 

36:      // Campo para data ou hora, vai depender do segundo parâmetro passado

37:      this.itDtField = new DateField("Data", DateField.DATE);

38: 

39:      //opções que irão aparecer na lista

40:      String itens[] = {"Opcao 1", "Opcao 2", "Opcao 3"};

41: 

42:      //EXCLUSIVE indica que será análogo a um RadioGroup

43:      this.itChGrp = new ChoiceGroup("",ChoiceGroup.EXCLUSIVE, itens, null);

44: 

45:      //adiciona-se os commands ao FORM

46:      this.form.addCommand(this.cmdVoltar);

47:      this.form.addCommand(this.cmdGravar);

48:      //seta o FORM como listener de commands,

49:      //e diz que quem vai tratar vai ser a própria classe

50:      this.form.setCommandListener(this);

51: 

52:      //adiciona-se os itens ao form (append sempre coloca o item no final da  

53:     //lista)

54:      this.form.append(this.itString);

55:      this.form.append(this.itTextField);

56:      this.form.append(this.itDtField);

57:      this.form.append(this.itChGrp);

58: 

59:      //main é referencia a ExemploWebMobile que contém a referencia ao display

60:      //e seta-se qual objeto vai agora ser mostrado na tela do celular

61:      this.main.setDisplayable(this.form);

62:    }

63:

64:    public void commandAction(Command c, Displayable d)

65:    {

66:       //se o command apertado for o Voltar

67:       if(c == this.cmdVoltar)

68:       {

69:          this.main.setDisplayable(null);

70:       }

71: 

72:       //se o Command apertado for o Gravar, que chama outra classe.

73:       if(c == this.cmdGravar)

74:       {

75:          //pode-se implementar por exemplo uma gravaçao desses dados em RMS

76:          new ExemploResultado(this.main,this);

77:       }

78:    }

79:}

Listagem 2. Código da classe ExemploFormItens.

 

image019.jpg

Figura 10. Aplicação rodando a classe ExemploFormItens.java.

 

Ao ser apertado o comando cmdGravar, será inicializada a classe ExemploResultado apresentada na Listagem 3, linhas 73-77 da Listagem 2. Passamos como parâmetro na sua chamada uma referência à classe principal e a classe ExemploFormItens para que os componentes selecionados possam ser recuperados na próxima tela. A classe ExemploResultado.java faz com que as opções e campos da tela anterior sejam mostradas como uma espécie de relatório. O resultado da implementação da Listagem 3 pode ser vista na Figura 11.

 

1: package br.com.webmobile;

2:

3: import javax.microedition.lcdui.*;

4: import java.util.*;

5:

6: public class ExemploResultado implements CommandListener

7: {

8:     private Form formResultados; //form que será usado para se mostrar os dados

9:     private StringItem telefone,data,opcao; //itens que mostrarão os dados

10:     private Command cmdVoltar; //command para voltar para a tela principal

11:     private ExemploWebMobile main; //referencia a tela principal da MIDlet

12:     private ExemploFormItens efi; //referencia a tela anterior de onde vieram os dados

13:

14:     public ExemploResultado(ExemploWebMobile prin, ExemploFormItens efi)

15:    {

16:         this.main=prin;

17:         this.efi=efi;

18:

19:         /**

20:          * É necessário tratar a data porque

21:          * se ela nao for preenchida ela vem como null

22:          * Abaixo são recuperados os dados do formulário anterior

23:          */

24:         String data;

25:         if(this.efi.itDtField.getDate()!=null)

26:         {

27:           Calendar date=Calendar.getInstance();

28:           date.setTime(this.efi.itDtField.getDate());

29:           data=date.get(Calendar.DAY_OF_MONTH)+"/"+(date.get(Calendar.MONTH)+1)+

30:                       "/"+date.get(Calendar.YEAR);

31:         }

32:         else

33:         {

34:             data="Data não selcionada";

35:         }

36:

37:         this.formResultados=new Form("Resultados");

38:

39:         //Como já vimos, o StringItem é um componente que aparece na tela

40:         //no formato label:valor

41:         this.telefone=new StringItem("Telefone:",this.efi.itTextField.getString());

42:         this.data=new StringItem("Data:",data);

43:         this.opcao=new   StringItem("Opção:",this.efi.itChGrp.getString(

44:                                      this.efi.itChGrp.getSelectedIndex()));

45:

46:         //os itens com os dados são adicionados ao form

47:         this.formResultados.append(this.telefone);

48:         this.formResultados.append(this.data);

49:         this.formResultados.append(this.opcao);

50:

51:         //command definido como BACK para que possa ficar no padrão do celular

52:         this.cmdVoltar=new Command("Voltar",Command.BACK,0);

53:

54:         //adiciona-se o comando e ativa o Form para capturar eventos

55:         this.formResultados.addCommand(this.cmdVoltar);

56:         this.formResultados.setCommandListener(this);

57:

58:         //é definido qual objeto aparecerá na tela do celular

59:         this.main.setDisplayable(this.formResultados);

60:     }

61:

62:     public void commandAction(Command c,Displayable d)

63:     {

64:         /**

65:          * se o command Voltar for selecionado a tela mostrada será

66:          * a list principal da MIDlet

67:          */

68:         if(c==this.cmdVoltar)

69:         {

70:             this.main.setDisplayable(null);

71:         }

72:     }

73: }

Listagem 3. Código da classe ExemploResultados.

 

 

image021.jpg

Figura 11. Visualização da classe ExemploResultados.java.

 

Ao apertar o comando Voltar, seremos redirecionados para a tela principal do aplicativo. Agora que já passamos pela implementação dos Itens, vamos aos Alerts. A classe ExemploListAlerts apresentada na Listagem 4 será inicializada no método commandAction (linha 112, Listagem 1) da classe principal (ExemploWebMobile). Nesta classe serão apresentados outros tipos de componentes, o Alerts. E para isso é criada uma lista (linhas 24-27) de diferentes tipos de alerta, um objeto Alert (linha 36) e um comando para voltarmos à tela principal (linha 21). O objeto alerta criado no construtor terá suas propriedades modificadas de acordo com a opção da List escolhida pelo usuário. Cada escolha de opção é tratada no método commandAction da interface CommandListener implementada nessa classe. Para esse tratamento, fazemos um switch (linhas 70-115) para podermos saber qual alert ativar de acordo com a opção (item da lista) selecionada. O resultado da Listagem 4 pode ser visualizada na Figura 12.

 

1: package br.com.webmobile;

2:

3: import javax.microedition.lcdui.*;

4:

5: public class ExemploListAlerts implements CommandListener

6: {

7:     private ExemploWebMobile main; //referencia a tela principal

8:     private Command cmdVoltar; //command que será usado para voltar a tela principal

9:     private List list; //list que será usado como Menu

10:    private Alert alert; //alert que será usado para criação dos exemplos

11:    private Image logo=null; //imagem que será mostrada nos alerts.

12:     

13:     public ExemploListAlerts(ExemploWebMobile princ)

14:     {

15:         this.main = princ;

16:     

17:         /**

18:          * Definiu-se o tipo do command como BACK, para que ele

19:          * possa ser posto na tela de acordo com o padrão do celular

20:          */

21:         this.cmdVoltar = new Command("Voltar", Command.BACK, 0);

22:     

23:         //itens que serão mostrados na lista como opções

24:         String itens[] = {"Alert Alarm", "Alert Confirmation", "Alert Error",

25:                           "Alert Info", "Alert Warning", "Alert Modal"   };

26:         //novamente não usamos imagens para os itens da lista

27:         this.list = new List("List",List.IMPLICIT, itens, null);

28:           

29:         // Carrega imagem .png para usar nos alerts

30:         try

31:         {

32:            this.logo=Image.createImage("/Logo.png");

33:         }

34:         catch(Exception e ){}

35:   

36:         this.alert = new Alert("Exemplo de Alertas", "Mensagem Padrão",

37:                                 this.logo, AlertType.ALARM );

38:     

39:         //adiciona-se o command a list

40:         this.list.addCommand(this.cmdVoltar);

41:         //define-se a list como sendo listener de commands

42:         this.list.setCommandListener(this);

43:     

44:         //seta-se o objeto que será mostrado na tela

45:         this.main.setDisplayable(this.list);

46:     }

47:     

48:     public void commandAction(Command c, Displayable d)

49:     {

50:         /**

51:          * se o command Voltar for selecionado a tela mostrada será

52:          * a list principal da MIDlet

53:          */

54:         if(c == this.cmdVoltar)

55:         {

56:             this.main.setDisplayable(null);

57:         }

58:     

59:         /**

60:          * Verifica qual dos itens da lista foi selecionado, e se foi através

61:          * da tecla de Select do celular.

62:          * Após verficação seta-se o tipo do alerta que será mostrado

63:          * e qual o tempo que ele ficará na tela do usuario

64:          * obs: Tempo em milisegundos.

65:          * É importante lembrar que as características apresentadas por

66:          * cada tipo de alert vai depender da implementação MIDP de cada aparelho.

67:          */

68:         if(c == List.SELECT_COMMAND && d == this.list)

69:         {

70:             switch(this.list.getSelectedIndex())

71:             {

72:                 case 0:

73:                    this.alert.setString("Mensagem de Alarme para o usuario!");

74:                    this.alert.setType(AlertType.ALARM);

75:                    this.alert.setTimeout(2000);

76:                    this.main.setDisplayable(this.alert);

77:                break;

78:         

79:                case 1:

80:                    this.alert.setString("Mensagem de Confirmação para o usuario!");

81:                    this.alert.setType(AlertType.CONFIRMATION);

82:                    this.alert.setTimeout(2000);

83:                    this.main.setDisplayable(this.alert);

84:                break;

85:         

86:                case 2:

87:                    this.alert.setString("Mensagem de Erro para o usuario!");

88:                    this.alert.setType(AlertType.ERROR);

89:                    this.alert.setTimeout(2000);

90:                    this.main.setDisplayable(this.alert);

91:                break;

92:         

93:                case 3:

94:                    this.alert.setString("Mensagem de Info para o usuario!");

95:                    this.alert.setType(AlertType.INFO);

96:                    this.alert.setTimeout(2000);

97:                    this.main.setDisplayable(this.alert);

98:                break;

99:         

100:                case 4:

101:                    this.alert.setString("Mensagem de Alerta para o usuario!");

102:                    this.alert.setType(AlertType.WARNING);

103:                    this.alert.setTimeout(2000);

104:                    this.main.setDisplayable(this.alert);

105:                break;

106:         

107:                case 5:

108:                    // Este alerta ficará na tela até que o usuário aperte um botao

109:                    this.alert.setString(

110:                            "Mensagem de Alerta para usuario, com tempo infinito!");

111:                    this.alert.setType(AlertType.WARNING);

112:                    this.alert.setTimeout(Alert.FOREVER);

113:                    this.main.setDisplayable(this.alert);

114:                break;

115:             }

116:         }

117:     }//fim do metodo

118: }//fim da classe

Listagem 4. Código da Classe ExemploListAlerts.

 

 

image023.jpgimage025.png

Figura 12. Lista de Alerts e o resultado do alert selecionado.

 

Assim finalizamos nosso exemplo sobre como manipular os componentes de interface com usuário do J2ME.

Conclusão

 Há muitos outros componentes que não vimos neste exemplo. Portanto, se você quiser conhecer mais sobre o J2ME, você deve estar sempre com a documentação ao seu lado. Se você tem o WTK instalado, a documentação está na pasta "/docs", ou você poderá achá-la no site da própria Sun Microsystems®. Pratique bastante e até uma próxima vez!