Java 2 ME
Interface
Prof. Afonso Ferreira Miguel, MSc
Java Micro Edition
(J2ME)
• Visão Geral:
– Plataforma de desenvolvimento voltada para 2
tipos de dispositivos:
• High-end consumer devices:
–
–
–
–
–
CDC (Connected Device Configuration)
TV interativa, Videofones, dispositivos wireless,...
Grande variedade de interfaces com usuário
Memória a partir de 2 a 4 Mb.
Conexão persistente e de banda larga, normalmente
TCP/IP
Java Micro Edition
(J2ME)
• Visão Geral:
– Plataforma de desenvolvimento voltada para 2
tipos de dispositivos:
• Low-end consumer devices:
–
–
–
–
CLDC (Connected Limited Device Configuration)
Telefones Celulares, pagers bi-direcionais, PDAs,...
Memória a partir de 128 kb
Conexão lenta, intermitente e normalmente não baseada
em TCP/IP.
– Utilizam baterias.
Java Micro Edition
(J2ME)
• Objetivos (CLDC):
–
–
–
–
Carga dinâmica de aplicações
Desenvolvimento por terceiros
Independência de padrões de rede
Compatibilidade com outros padrões wireless
Java Micro Edition
(J2ME)
• Dispositivos alvo (CLDC):
– pelo menos 160kb de memória disponível para
Java
– Processador entre 8 e 32 MHz, 16 ou 32 bit
– Alimentado por bateria
– Conectividade limitada (9600 bps ou menos)
– Produção em alta escala
Java Micro Edition
(J2ME)
Profile(s)
Configuration
{
Bibliotecas
JVM
Sistema Operacional
Java Micro Edition
(J2ME)
• K Virtual Machine (KVM):
–
–
–
–
Pequena: núcleo a partir de 60kb
Altamente portável
modular e customizável
Desenvolvida para dispositivos a partir de
128kb de memória
Java Micro Edition
(J2ME)
• MIDlets
– Unidade básica de execução do MIDP
– Derivada de javax.microedition.MIDlet
– 3 métodos abstratos
• startApp, pauseApp, destroyApp
Java Micro Edition
(J2ME)
• startApp()
– Invocado quando da inicialização e reinicialização do
Midlet
– Deve obter os recursos necessários para execução
(timers, conexões de rede)
– É invocado mais do que uma vez
– Pode falhar de 2 maneiras:
• transient: a falha é temporária (ex. falha de conexão). O
MIDlet pode avisar ao sistema para reiniciá-lo mais tarde
lançando uma MIDletStateChangeException
• non-transient: Erro fatal. Pode ser tratado ou lançado para o
sistema que irá invocar o método destroyApp
Java Micro Edition
(J2ME)
• pauseApp()
– Invocado toda a vez que o MIDlet é “colocado
em pausa”
– Quando receber a notificação, o MIDlet deve
liberar tantos recursos quanto possível e
permanecer em dormência.
– Não é obrigatório, porém o sistema pode optar
por terminar a execução de MIDlets que não
atenderem a requisição.
Java Micro Edition
(J2ME)
• destroyApp(boolean)
– Invocado quando o MIDlet está para ser
destruído.
– O parâmetro indica se a destruição é
incondicional. Caso negativo, o MIDlet pode
requisitar uma “stay of execution” lançando
uma exceção MIDletStateChangeException
Java Micro Edition
(J2ME)
• Transição de Estados
new HelloWorld()
notifyPaused
pauseApp
Paused
startApp
Active
resumeRequest
destroyApp
destroyApp
notifyDestroyed
notifyDestroyed
Destroyed
Métodos do MIDlet para forçar mudança de estado
Java Micro Edition
(J2ME)
• Estrutura da UI
– Cada MIDlet possui um Display, onde uma instância de
Displayable é mostrada de cada vez
– A aplicação seta o Displayable corrente de acordo com
a evolução do sistema e as interações com o usuário
– Dois tipos de Displayable
• Canvas: baixo nível
• Screen: alto-nível, encapsulamento de componentes de UI
Java Micro Edition
(J2ME)
Alert
Display
Screen
0..1
Displayable
Canvas
List
StringItem
TextBox
ImageItem
Form
TextField
DateField
0..n
Item
Gauge
ChoiceGroup
Command
Java Micro Edition (J2ME)
Estrutura básica de um MIDlet
1ª aplicação... ... Hello World
Passo 1: Criando projeto no J2ME Wireless Toolkit
•Criar projeto com botão New Project...
•Pressionar OK
1ª aplicação... ... Hello World
Passo 2: Criando projeto no JCreator
•Criar um Empty Project no diretório c:\Wtk104\apps\ com o
mesmo nome do projeto criado no J2ME Wireless Toolkit
(MeuTeste);
•Criar um Java File chamado HelloWorld.java no diretório
c:\Wtk104\apps\MeuTeste\src\
1ª aplicação... ... Hello World
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.*;
Passo 3: código Java
public class HelloWorld extends MIDlet implements CommandListener
{
private Form form;
•Entrar com o código a seguir:
•Salvar
public HelloWorld()
{
form = new Form("Isto é um teste");
form.append("Olá Mundo!");
form.addCommand( new Command( "Sair", Command.EXIT, 1 ) );
form.setCommandListener( this );
}
public void startApp()
{
Display display = Display.getDisplay(this);
display.setCurrent( form );
}
public void pauseApp()
{
}
public void destroyApp(boolean unconditional)
{
form = null;
}
public void commandAction(Command c, Displayable d)
{
destroyApp(true);
notifyDestroyed();
}
}
1ª aplicação... ... Hello World
Passo 4: compilando e testando...
•Voltar ao J2ME Wireless Toolkit compilar o projeto
com o botão Build;
•Selecionar o device a ser emulado (Motorola_i85s);
•Executar através do botão Run;
•Selecionar a aplicação e executá-la através do botão
Launch.
Java Micro Edition (J2ME)
Display: é a interface de tela padrão. Para obtê-la,
devemos evocá-la no construtor do MIDlet
utilizando:
Java Micro Edition (J2ME)
TextBox: caixa de texto Displayable. Para ser exibida, deve
ser:
• Definida em uma referência;
• Criada utilizando new e com os parâmetros adequados;
• Exibida conectando-se ao display padrão (no método
start).
Java Micro Edition (J2ME)
Exercício 1: Crie um novo projeto chamado Midlet1 criando
também uma caixa de texto. Compile (corrigindo os erros) e:
1. Verifique o aspecto desta caixa de texto e as formas de
digitação nos diferentes tipos de aparelhos (iDEN, PALM,
etc.);
2. Substitua o parâmetro constraints e verifique o resultado
na digitação.
Java Micro Edition (J2ME)
List: lista que exibe várias opções.
Opções podem ser listadas no construtor ou utilizando o
método append. A princípio, colocar null na lista de imagens.
Java Micro Edition (J2ME)
Exercício 2: modifique o projeto Midlet1 retirando o TextBox
e adicionando o List. Compile (corrigindo os erros) e:
1. Verifique o aspecto da lista e as formas de seleção nos
diferentes tipos de aparelhos (iDEN, PALM, etc.);
2. Teste as várias opções do parâmetro listType e verifique o
resultado na seleção;
3. Modifique o código para utilizar o ouro construtor.
Java Micro Edition (J2ME)
List com Imagens:
As imagens são carregadas a partir do diretório src do projeto. Para
criar uma imagem utiliza o método estático Image.createImage(“...");
Java Micro Edition (J2ME)
Exercício 3: modifique o projeto Midlet1 adicionando uma
mesma imagem a cada opção da lista.
Java Micro Edition (J2ME)
Form:
Formulário é um Displayable que permite a
adição de diferentes tipos de controles (chamados
de Item).
Form
StringItem
ImageItem
TextField
DateField
0..n
Item
Gauge
ChoiceGroup
Java Micro Edition (J2ME)
Form: o processo de criação de um Form é semelhante ao
TextBox e List.
Java Micro Edition (J2ME)
Form: uma vez criado o formulario, podemos adicionar os
controles
TextField: campo de texto
Java Micro Edition (J2ME)
Exercício 4: modifique o projeto Midlet1 adicionando um
formulário que solicite as informações Nome e Telefone. Testeo nos vários Handsets.
Java Micro Edition (J2ME)
Form:
StringItem: string fixa.
Java Micro Edition (J2ME)
Exercício 6: modifique o formulário do item anterior
adicionando o nome da empresa (“HAL INC”) no início.
Java Micro Edition (J2ME)
Form:
ChoiceGroup: lista com itens permitindo
seleção simples e múltipla. Os itens podem
ser listados no construtor ou com o comando
append.
Java Micro Edition (J2ME)
Exercício 7: modifique o formulário do item anterior
adicionando a seleção do estado civil (Solteiro/Casado). Os
itens do controle ChoiceGroup devem ser adicionados com o
comando append.
Java Micro Edition (J2ME)
Form:
DateField: seleção de Data e/ou Hora.
Java Micro Edition (J2ME)
Exercício 8: adicione o controle DateField no formulário
anterior e verifique as opções DATE, DATE_TIME e TIME.
Java Micro Edition (J2ME)
Form:
Gauge: barra de progresso com ou sem
seleção.
Java Micro Edition (J2ME)
Exercício 9: retire alguns itens do formulário anterior (para
facilitar a visualização) e adicione um Gauge. Teste as opções
interactive.
Java Micro Edition (J2ME)
Form:
ImageItem: imagem estática.
Java Micro Edition (J2ME)
Exercício 10: elimine todos os itens do formulário anterior
(para facilitar a visualização) e um ImageField com uma figura
e um StringField com o nome da imagem. Visualize em
diferentes dispositivos.
Java Micro Edition (J2ME)
Command
Command são controles adicionados ao
handset como hotkeys ou menus.
Java Micro Edition (J2ME)
Command
A adição do Command no projeto é feita em
um objeto Displayable. Observe que o
construtor possui 3 parâmetros.
Java Micro Edition (J2ME)
Exercício 11: modifique o MIDlet implementado adicionando
3 comandos com prioridades diferentes: “Sair”, “Novo”,
“Excluir”. Localize cada um dos comandos nas telas
apresentadas.
Java Micro Edition (J2ME)
Command
Tratando eventos do
Command:
Para tratar os eventos dos
botões, uma classe deve
implementar a interface
CommandListener.
Java Micro Edition (J2ME)
Command
Esta interface obriga a
classe a implementar o
método commandAction
que é evocado quando
algum comando do
Displayable é solicitado.
Java Micro Edition (J2ME)
Command
A seguir, o Displayable
precisa ser informado qual
a classe que deverá
receber os eventos. Para
isto, é utilizado o método
setCommandListener.
Java Micro Edition (J2ME)
Command
Por fim, visto que vários
botões podem solicitar
eventos, é necessário que
a função commandAction
identifique o comando e
execute o código
necessário.
Comandos necessários
para encerrar o programa
Java Micro Edition (J2ME)
Exercício 12: modifique o MIDlet implementado adicionando
a funcionalidade de “Sair”. Adicione também uma mensagem
(System.out.println(“...”)) aos comandos “Novo” e “Excluir”.
Teste nos Handset padrões e no PALM.
Java Micro Edition (J2ME)
Trocando a tela
Para navegar entre
Displayables as telas podem
ser comutadas utilizando
o comando setCurrent().
Java Micro Edition (J2ME)
Exercício 13: modifique o MIDlet do exercício anterior
adicionado um novo Displayable do tipo List. Neste último
adicione um Command “Volta”. Adicione a funcionalidade
necessária para que ao pressionar o botão “Novo”, o List seja
exibido, e ao pressionar “Volta”, o formulário volte a ser
exibido.
Java Micro Edition (J2ME)
List ou ChoiceGroup com múltiplas opções
CAST
Java Micro Edition (J2ME)
Exercício 14: modifique o MIDlet do exercício anterior para
exibir com o comando System.out.println os valores de estado
dos itens do List (modificá-lo para MULTIPLE).
Java Micro Edition (J2ME)
Exercício 15: implementar um programa que exiba uma lista
de nomes (1). Ao pressionar um botão “Novo” uma tela
solicitará um novo nome (2). Ao entrar com um novo nome, a
lista original será atualizada(3). Estando um nome selecionado,
ao pressionar o botão “Excluir”, este nome deverá desaparecer
da lista.
(1)
(2)
(3)
J2ME
Display Gráfico
Alert
Display
Screen
0..1
Displayable
Canvas
List
StringItem
TextBox
ImageItem
Form
TextField
DateField
0..n
Item
Gauge
ChoiceGroup
Command
J2ME
Classe Canvas
Canvas é um Displayable do tipo abstract. Assim, não pode
gerar uma instância direta.
J2ME
Classe Canvas
Para criar um objeto do tipo Canvas, é necessário criar uma
subclasse, e instanciá-la. Observe os métodos abstratos da
classe Canvas.
Java Micro Edition (J2ME)
Exercício 16: implementar um MIDlet que exiba uma classe
derivada da Canvas. Modifique o código do método paint para
o mostrado abaixo e veja o resultado:
J2ME
Canvas
Métodos chaves da classe Canvas:
paint: método evocado sempre que a Canvas precisa ser “pintada” na
tela. Obs.: este método nunca deve ser evocado diretamente pelo
programa do usuário;
repaint: método que pode ser evocado pelo programa do usuário
solicitando que a tela seja “repintada”;
getHeight: retorna ao programa do usuário a altura da tela em pixels;
getWith: retorna ao programa do usuário a largura da tela em pixels;
hasPointerEvents: retorna true se o dispositivo aceita entradas do
ponteiro (caneta, mouse, etc...);
hasPointerMotionEvents: retorna true se o dispositivo aceita
entradas de movimento do ponteiro (drag);
J2ME
Graphics
Um objeto da classe Graphics é utilizado como parâmetro do
método paint. Este objeto é a representação do display gráfico.
Para alterar o conteúdo da tela, devemos utilizar os métodos
deste objeto:
J2ME
Graphics
Métodos chaves da classe Graphics:
setColor: define a cor da caneta para pintar neste objeto;
drawLine: desenha uma linha simples;
drawRectangle: desenha um retângulo vazado;
drawRoundRect: desenha um retângulo vazado com cantos
arredondados;
drawArc: desenha um arco ou círculo vazado;
fillRectangle: desenha um retângulo cheio;
fillRoundRect: desenha um retângulo cheio com cantos
arredondados;
drawArc: desenha um arco ou círculo cheio;
drawImage: pinta uma imagem no Canvas;
J2ME
Graphics
Métodos para texto da classe Graphics:
setFont: define a fonte para escrever textos;
drawChar , drawChars: escreve um ou mais caracteres na
tela. Obs.: verificar os parâmetros de âncora (anchor);
drawString , drawSubstring: escreve uma string na tela.
Obs.: verificar os parâmetros de âncora (anchor);
J2ME
Graphics
“ Clip: área que poderá ser afetada pelos métodos de desenho.
Desenhos fora desta área não aparecerão.”
Métodos para clipping e mudança de referência da classe
Graphics:
setClip: define uma nova área para clipping;
clipRect: redefine a área de clipping para a intersecção da
área atual e um retângulo;
translate: redefine uma posição de origem (0,0). Todos os
métodos para desenho serão a partir desta nova origem.
Java Micro Edition (J2ME)
Exercício 17: implementar um MIDlet que exiba uma “cara
sorridente” com olhos, nariz e boca, que ocupe a tela inteira,
independente do dispositivo. Adicione também um Command
para encerrar o MIDlet.
J2ME
Canvas
Eventos: vários métodos relativos a eventos são definidos na
classe Canvas:
keyPressed: chamado quando uma tecla é pressionada;
keyReleased: chamado quando uma tecla é solta;
pointerPressed: chamado quando o ponteiro (mouse,
caneta) é pressionado em uma posição da tela;
pointerDragged: chamado quando o ponteiro (mouse,
caneta) é arrastado. É chamado a cada nova posição;
pointerReleaser: chamado quando o ponteiro (mouse,
caneta) é solto;
Java Micro Edition (J2ME)
Exercício 18: implementar um MIDlet que exiba uma bola no
local onde a tela do PALM for pressionada. Observe que este
programa não funcionará com outros dispositivos sem tela
sensível.
J2ME
Threads
Assim como em C, Threads são muito fáceis de implementar e
podem ser aplicadas em diversas áreas. Uma muito comum,
é a animação.
Para a construção de threads, temos duas opções:
1) Criar uma subclasse da classe Thread;
2) Adicionar a interface Runnable a uma classe já existente.
J2ME
Threads
Criar uma Thread a partir de uma subclasse da classe Thread;
Para disparar a subclasse como uma Thread, basta:
J2ME
Threads
Criar uma Thread a partir de uma classe que implementa
Runnable;
Para disparar a subclasse como uma Thread, basta:
J2ME
Threads
Observações com relação a Thread:
•
•
A Thread será encerrada ao encerrar o método run(). Laços
de repetição podem ser utilizados para que a Thread seja
executada por um longo tempo;
Para suspender a execução da Thread por algum tempo,
utilize o método estático Thread.spleep();
Java Micro Edition (J2ME)
Exercício 19: modificar a classe Canvas para que implemente
Runnable. No método run(), implemente um laço repetitivo
que imprima uma mensagem através do System.out.println.
Faça este laço ser repetido a cada 1s (utilize
Thread.sleep(1000) ).
Java Micro Edition (J2ME)
Exercício 20: modificar a classe do exercício 19 para que a
bola se mova diagonalmente cada 10ms. Após visualizar a bola
em movimento, modifique o código para a bola ficar rebatendo
nas bordas.
J2ME
Threads
Efeito de cintilação:
•
Aplicações que exigem animação geralmente executam o
laço repetitivo:
1. Desenha;
2. Apaga;
3. Redesenha;
4. Apaga;
5. ...
Porém, o tempo entre apagar e redesenhar muitas vezes
provoca um cintilar (pisca-pisca) para o usuário,
reduzindo o efeito de animação.
Java Micro Edition (J2ME)
Exercício 21: modificar o exemplo do exercício 20 para
aparecer uma bola com 80 pixels de diâmetro. Observe que a
bola algumas vezes parece não ser desenhada corretamente.
J2ME
Threads
Duplo buffer: para minimizar os efeitos da cintilação, o
processo de animação pode ser modificado para:
1. Desenha;
2. Sobrescreve;
3. Redesenha;
4. Sobrescreve;
5. ...
Com isto, a tela nunca será apagada, evitando o efeito
pisca-pisca.
J2ME
Threads
buffer
Image
drawImage(...)
Para evitar a cintilação, primeiramente devemos desenhar
em uma imagem previamente criada, para depois
sobrescrevê-la no display gráfico.
Java Micro Edition (J2ME)
Exercício 22: modificar o exemplo do exercício 21 para que o
desenho seja realizado em um buffer (objeto) do tipo Image,
sendo atualizado na tela posteriormente.
Obs.: o apagamento agora deve ser feito no buffer.
J2ME
Teclas
Os eventos de teclado são baseados em códigos de qualquer
tecla e em códigos de teclas dedicadas para jogos.
Para um Canvas tratar uma tecla, esta deve ser capturada
pelos eventos:
keyPressed: chamado quando uma tecla é pressionada;
keyReleased: chamado quando uma tecla é solta.
E pode ser tratada pelo evento:
getGameAction: recupera o código de jogo de uma tecla.
J2ME
Teclas
Exercício 23: modificar o exemplo do exercício 22 para que
uma mensagem seja exibida pelo System.out.println. Utilize o
método getGameAction em um case e mostre uma mensagem
customizada.
J2ME
Teclas
Exercício 24: diminua o tamanho da bola para 10 e adicione
uma pequena raquete na parte inferior da tela que é movida
pelo teclado.
Adicione uma variável “estado” que é inicializada com 0;
Adicione um botão (Command) que faça “estado”=1;
Modifique o código para que permita a movimentação da bola
apenas quando “estado”=1;
Por fim, caso a bola não rebata na raquete, faça “estado”=0.
J2ME
Comunicação
J2ME tem permite que dispositivos com suporte a rede
possam tirar proveito disso. Desta forma, classes foram
criadas para fazer acesso UDP, TCP inclusive HTTP, etc.
O principal método para acesso é o Connector.open.
Este método permite criar conexões para diferentes
protocolos seguindo o padrão:
J2ME
Comunicação
•Comunicação em Rede
Datagrama:
Para melhor controle dos dados recebidos, é conveniente que
processos de recepção sejam colocados em uma Thread
separada. Isto permite que o programa principal possa receber
dados enquanto está sendo executado.
Datagrama
J2ME
Comunicação
J2ME
Teclas
Exercício 25: modifique o exercício 24 para que a cada
rebatida, um datagrama seja enviado para sua máquina(IP
127.0.0.1). Utilize a classe Comm criada pelo professor.
Experimente mudar o IP para enviar o datagrama ao colega.
J2ME
Comunicação
• Comunicação em Rede
– Protocolo HTTP
– Utilizando uma requisição GET:
HttpConnection c = (HttpConnection)Connector.open(“http://java.sun.com”);
int status = c.getResponseCode();
if(status != HttpConnection.HTTP_OK){
...
}
else {
InputStream is = c.openInuptStream();
...
is.close();
}
c.close();
J2ME
Comunicação
J2ME
Comunicação
Exemplo: HTTPTest
J2ME
Teclas
Exercício 26: modifique o sistema de controle do exercício 15
para que acesse a página http://10.26.134.100/bd.asp) que
controla um banco de dados de nomes) para que todos os
nomes sejam lidos e atualizados remotamente.
J2ME
Teclas
Avaliação: modificar o programa do exercício 24 para arquivar
no banco de dados remoto (HTTP) o nome do jogador e o
número de pontos.
Java Micro Edition
(J2ME)
• Persistência (Record Management System - RMS)
– Fornece records e Record Stores
RecordStore
Record 1
Record 17
Record 10
Record 2
– MIDP garante que um registro manterá seu recordId até
que seja deletado.
– Um recordId é gerado por um algoritmo de incremento
unitário monotônico
Java Micro Edition
(J2ME)
• Acessando RecordStores
– Identificados por um nome de até 32 caracteres Unicode,
únicos por MIDlet suite
•
•
•
•
•
•
RecordStore.listRecordStores: lista os RecordStores da suite;
RecordStore.open(String, boolean): abre (ou cria) um RecordStore
RecordStore.close()
RecordStore.delete(String): remove um RecordStore
RecordStore.getNumRecords(): Número de registros no RS
RecordStore.getVersion(): Versão do RS, incrementada a cada
operação de inserção, alteração ou exclusão de registro
• RecordStore.getLastModified: Hora da última modificação
Java Micro Edition
(J2ME)
– Manipulando Registros
•
•
•
•
•
addRecord(byte[] data, int offset, int length)
deleteRecord(int Id)
getRecordSize(int Id)
getRecord(int id)
setRecord(int Id, byte[]data, int offset, int length)
– Convertendo dados para array de bytes:
• ByteArrayOutputStream
• DataOutputStream
Java Micro Edition
(J2ME)
– Filtrando Registros
public interface RecordFilter
{
public boolean matches(byte[] candidate);
}
– Comparando Registros
public interface RecordComparator
{
public int compare(byte[] b1, byte[] b2);
public static final int EQUIVALENT;
public static final int FOLLOWS;
public static final int PRECEDES;
}
Download

JAVA2ME Interface - Afonso Ferreira Miguel, MSc