Tutorial: Como criar e trabalhar com imagens em aplicações J2ME

app.jpgNeste artigo mostrarei como carregar e usar imagens em aplicações J2ME de dois modos, usando Canvas, interface gráfica de baixo nível, e usando interface gráfica de alto nível, no caso, Form, List, etc. A primeira tela será uma tela Splash em Canvas com a logo da aplicação, e depois de alguns segundos automaticamente será carregada a tela inicial da aplicação, um Form. Ensinarei também a onde colocar corretamente os arquivos de imagens, de modo que quando for criado o JAR as imagens fiquem dentro dele.

Sobre os tipos de Imagens

Podemos usar tipos diferentes de imagens em nossas aplicações J2ME, mas nem todos os celulares que aceitam vários tipos. Por exemplo, alguns celulares reconhecem JPG e PNG-24, mas outros não. No entanto, todos reconhecem o formato PNG-8. Portanto, se sua aplicação precisa rodar em muitos dispositivos diferentes, use PNG-8, que normalmente é o formato que deixa a imagem com o menor tamanho final, comparando-se com JPG e PNG-24.

Caso o celular aceite PNG-24 ou JPG, mesmo assim aconselho a continuar usando como padrão PNG-8, e só usar JPG ou PNG-24 quando for mais viável. Por exemplo, uma foto em JPG normalmente ficará menor do que a mesma foto em PNG-8, assim, caso o celular reconheça JPG, aconselho a usar esse formato para reduzir o tamanho final de sua aplicação.

Posso usar PNG-24 se o celular reconhece esse formato? Sim, mas prefira PNG-8. Use PNG-24 apenas para imagens que necessitem de pixels semi-transparentes, pois normalmente uma imagem em PNG-24 fica maior que PNG-8. Lembre-se que PNG-8 permite pixels transparentes também, mas apenas PNG-24 permite pixels semi-transparentes.

Criando as imagems

Para criar as imagens, você pode usar o CorelDraw e/ou Photoshop. Eu crio as imagens em CorelDraw, vetorizadas. Depois exporto do CorelDraw para o Photoshop, já no tamanho final que a imagem ficará no celular. Depois abro no Photoshop e faço alguns reparos, e finalmente exporto do Photoshop o seu ótimo assistente “Salvar para Web” que me permitirá analisar e escolher qual formato escolher, PNG-8, PNG-24 ou JPG.

Exemplo: Em nossa aplicação usaremos essa imagem final na tela Canvas. Eu criei primeiro essa imagem no CorelDraw X3. Se quiser, pode baixar o arquivo aqui. Veja a tela do CorelDraw com a imagem vetorizada:
img1.jpg

Depois, ainda no CorelDraw, exportei para o Photoshop como arquivo do tipo PSD, definindo o tamanho final da minha imagem no celular, que será de 128 pixels de largura. Então abri o arquivo PSD exportado no Photoshop, como mostra:
img2.jpg

Então fiz alguns reparos, como cortar a imagem 1 pixel pelas beiradas para que não fique sujeira nas bordas. E por último, fui em File, Save for web, escolhi PNG-8 e salvei numa pasta temporária, para que daqui a pouco, quando eu for criar a aplicação, eu copie essa imagem PNG exportada da pasta temporária para a pasta src do meu projeto, onde ficam os fontes.
img3.jpg

Criando o projeto no NetBeans 6

Vamos criar nosso projeto. No NetBeans clique no menu File, New Project. Escolha a categoria Mobility, e selecione MIDP Application. Clique em Next. No nome do projeto colocaremos “MobileImage”. Escolha a pasta que seu projeto ficará. Desative a opção “Create Hello MIDlet” e clique em Next. Escolha o emulador, como mostra a imagem abaixo, ou outro que preferir. Clique em Finish.
img4.jpg

Agora criaremos nosso MIDlet responsável por controlar a aplicação e abrir as telas. Clique com o botão direito em <default package>, New, MIDlet. Coloque o nome dele como “MobileImageApp” e clique em Finish.

img5.jpg

Nessa classe, crie uma variável estática chamada app, do mesmo tipo da classe, que guardará a referência única ao nosso MIDlet, para que as outras telas possam facilmente chamar algum método que ele tenha, afinal, é ele que controlará as nossas telas, ele é o controlador da aplicação. Quando a aplicação iniciar, será chamado o método startApp() e dentro desse método nós guardaremos a referência na variável app. Veja como ficou nossa classe MobileImageApp:

public class MobileImageApp extends MIDlet {
    public static MobileImageApp app; //Referência ao MIDlet
    public void startApp() {
        //Guarda a referência do MIDlet numa variável estática
        //para poder ser acessada de qualquer tela
        app = this;
    }
    public void pauseApp() {
    }
    public void destroyApp(boolean unconditional) {
    }
}

Crie também dois métodos nessa classe que serão implementados e usados posteriormente, mas que já queremos existentes. mostraTelaCanvas e mostraTelaForm. Eles servirão para mostrar as respectivas telas. Quando a aplicação inicia, temos que chamar o método mostraTelaCanvas, para que a tela inicial seja mostrada. Nossa classe, alterada, ficará assim:

public void startApp() {
    //Guarda a referência do MIDlet numa variável estática
    //para poder ser acessada de qualquer tela
    app = this;
    //Mostra a tela Splash quando inicia a aplicação
    mostraTelaCanvas();        
}
public void mostraTelaCanvas() {
}   
public void mostraTelaForm() {
}   
public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

Onde colocar o arquivo da imagem?

Precisamos colocar os arquivos de imagens dentro do nosso projeto, de tal forma que quando o NetBeans gerar o JAR, as imagens sejam colocadas nele. Temos 2 formas de fazer isso:

1- Colocando diretamente na pasta SRC do projeto.

Todos os arquivos que estiverem na pasta SRC serão automaticamente adicionados ao JAR. Assim sendo, nossas imagens seriam colocadas no JAR automaticamente caso fossem colocadas na pasta SRC. Esse é o mais indicado caso você tenha pouca experiência.

2- Criando uma pasta chamada res dentro da pasta do projeto do NetBeans, e colocando as imagens lá dentro.

Depois disso, será necessário entrar nas propriedades do projeto no NetBeans e adicionar a pasta na sessão Libraries & Resources. O inconveniente é que se você envia o projeto para alguém, ou muda a pasta do projeto de lugar, você sempre deverá readicionar essa pasta nas propriedades do projeto.

Sendo na pasta RES, ou na pasta SRC, você pode ou não adicionar as imagens em subpastas. Por exemplo, dentro da pasta SRC você poderia criar uma subpasta chamada img e colocar todas as imagens nessa subpasta. Ou então poderia colocá-las todas dentro da pasta SRC raiz, diretamente.

Mas lembre-se que se usar subpastas e pacotes em suas aplicações J2ME, isso reduzirá um pouquinho a performance, principalmente em celulares com pouco poder de processamento.

Em nossa aplicação exemplo, colocaremos todas as imagens diretamente na pasta SRC. Portanto, fui naquela pasta temporária em que havia salvo a imagem PNG-8 e copie para a pasta SRC do meu projeto.

Use essas imagens prontas

Para fazer o tutorial, use essas 2 imagens abaixo. Clique com o botão direito nelas e escolha Salvar Imagem Como. Grave na pasta SRC do seu projeto no NetBeans. Os nomes dos arquivos salvos devem ser “logo.png” e “mensagem.png”, tudo minúsculo.

logo.png mensagem.png

Criando a tela Splash em Canvas com Imagem

A primeira tela será nossa tela Splash. Quando entrarmos na aplicação essa tela aparecerá por alguns segundos, e depois disso, automaticamente abrirá a próxima tela.

Para criamos a tela Canvas, clique com o botão direito em <default package>, New, Java Class. Dê o nome de TelaCanvas e clique em Finish. Será criada uma classe como mostra a imagem logo abaixo. Faça com que essa classe estenda a classe Canvas, importe e implemente os métodos necessários. Deverá ficar como abaixo:
<IMG6>

Nossa imagem será carregada no construtor da classe e guardada numa variável, para que sempre que for chamado o método paint que pintará a tela, não precisemos recarregar a imagem novamente. Vamos criar a variável que guardará a nossa imagem. Veja como ficará a declaração da variável e o construtor da classe que já carrega a imagem:

import java.io.IOException;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

public class TelaCanvas extends Canvas {
    Image imagem; //Imagem que será pintada
    public TelaCanvas() {
        //Configura a tela Canvas para ficar em tela cheia
        setFullScreenMode(true);        
        //Carrega a imagem
        try {
            imagem = Image.createImage(”/logo.png”);
        } catch (IOException ex) {
            System.out.println(”Não foi possível carregar a imagem”);
        }
    }
    protected void paint(Graphics arg0) {
        throw new UnsupportedOperationException(”Not supported yet.”);
    }
}

Perceba que no construtor, ao carregarmos a imagem, informamos o caminho do arquivo referente à pasta src. Se nossa imagem estivesse numa subpasta dentro da pasta SRC, então teríamos que informar algo como “/imagens/logo.png”.

Agora vamos fazer com que nossa tela pinte a imagem na tela, bem como pinte o fundo da tela da mesma cor de fundo da imagem, cinza escuro. Dentro do método paint() coloque o seguinte:

protected void paint(Graphics graphics) {
    //Define a cor atual como cinza escuro, que será usado na próxima instrução
    graphics.setColor(0xff333333); 
    //Pinta um retângulo por toda a tela, usando a cor atual definida
    graphics.fillRect(0, 0, getWidth(), getHeight());
    //Pinta a imagem no centro da tela. Para isso, deve-se calcular o X e o Y
    //previamente, tomando por base as medidas da imagem e da tela.
    int x = (getWidth() / 2) - (imagem.getWidth() / 2);
    int y = (getHeight() / 2) - (imagem.getHeight() / 2);
    graphics.drawImage(imagem, x, y, Graphics.TOP | Graphics.LEFT);
}

Criamos nossa tela Splash! Agora vamos criar nossa segunda tela, o Form.

Criando a tela Form

A tela Splash será mostrada por 4 segundos durante o carregamento da aplicação, e logo em seguida será mostrada a tela Form, a tela inicial da aplicação.

Para criamos a tela Form, clique com o botão direito em <default package>, New, Java Class. Dê o nome de TelaForm e clique em Finish. Será criada uma classe. Faça com que essa classe estenda a classe Form e implemente a interface CommandListener, importe e implemente os métodos necessários. Crie o construtor da nossa classe. Deverá ficar como abaixo:

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;

public class TelaForm extends Form implements CommandListener {
    public TelaForm() {
        super(”DevMobile”);
    }
    public void commandAction(Command comando, Displayable tela) {   
    }
}

Vamos fazer com que nossa tela tenha um comando chamado Sair. Para isso, altere o construtor para que fique como mostra abaixo:

public TelaForm() {
    super(”DevMobile”);
    //Adiciona o comando SAIR à tela
    addCommand(new Command(”Sair”, Command.EXIT, 0));
    //Define a tela como interpretadora dos eventos de comandos
    setCommandListener(this);
}

Para que esse comando feche a aplicação quando for chamado, altere o método commandAction, como mostra abaixo:

public void commandAction(Command comando, Displayable tela) {
    //Verifica se o comando é o comando SAIR
    if (comando.getCommandType() == Command.EXIT)
        MobileImageApp.app.notifyDestroyed(); //Fecha a aplicação
}

Agora criaremos os controles da nossa tela, e adicionaremos duas imagens. Tudo isso será feito no construtor da tela. Veja como ficou nosso contrutor:

public TelaForm() {
    super(”DevMobile”);
    //Adiciona o comando SAIR à tela
    addCommand(new Command(”Sair”, Command.EXIT, 0));
    //Define a tela como interpretadora dos eventos de comandos
    setCommandListener(this);
    try {
        //Carrega e adiciona a imagem do logo à tela
        append(Image.createImage(”/logo.png”));
        //Adiciona um espaço entre as duas imagens
        append(new Spacer(getWidth(), 10));
        //Carrega e adiciona a imagem da mensagem à tela
        append(Image.createImage(”/mensagem.png”));
    } catch (IOException ex) {
        System.out.println(”Imagens não carregadas”);
    }    
    //Adiciona outros controles à tela
    append(new StringItem(”Mensagem”, “Ande sempre de mãos dadas com quem você ama.”));
}

Pronto!!! Criamos nossa tela Form. Agora basta alterarmos nossa classe MIDlet para que abra as telas corretamente. Teremos que alterar apenas os dois métodos que criamos para as telas. Veja como devem ficar:

public void mostraTelaCanvas() {
    //Cria e mostra a tela Splash
    Display display = Display.getDisplay(app);
    display.setCurrent(new TelaCanvas());
      
    //Agenda um evento para que daqui a 4 segundos seja mostrada 
    //a outra tela, a tela Form, ocultando a tela Splash.
    new Timer().schedule(new TimerTask() {
        public void run() {
            app.mostraTelaForm();
        }
    }, 4000);
}
public void mostraTelaForm() {
    //Cria e mostra a tela Form
    Display display = Display.getDisplay(app);
    display.setCurrent(new TelaForm());
}

Conclusão

Com o projeto pronto, clique no menu Run, Run Main Project. Deverá abrir o emulador como mostra a imagem:
img7.jpg

Vimos que é muito fácil criar e usar imagens em aplicações J2ME. Podemos usar tanto em telas Canvas, quanto telas Form.

Se desejar baixar todo o código fonte do projeto, de forma que você possa descompactar e abrir no NetBeans, clique aqui.

Boas aplicações!



Sobre o Autor

Este artigo foi escrito por Nelson Pereira Junior.
Nelson é desenvolvedor há 12 anos. Hoje desenvolve aplicações Web e Móveis na Abacomm Brasil cuidando do desenvolvimento server-side J2EE, banco de dados, design de aplicações móveis, e desenvolvimento móvel usando várias plataformas como BlackBerry, J2ME, FlashLite, Android, etc. Para conversar com o autor use o e-mail, MSN e GTalk npereirajr@gmail.com.



Receba artigos em seu e-mail

Receba os novos artigos do blog em seu e-mail. E-Mail:



7 Comentários

  1. Rafael Durelli:

    Muito boa iniciativa como sempre cara, meus parabens !

  2. washington:

    ótimo tutorial…fiz e foi muito fácil…pra quem esta começando a mexer com j2me…..parabens
    abraço

  3. Ausli Sena:

    Só pra comcluir.. o link de download dos fonte, Clik aqui.. esta furado ….abraço

  4. Diego:

    Cara gostei muito. ótima explicação. Parabéns
    pretendo fazer um tutorial desse com o meu tcc que vai ser um afinador de violão

  5. Ricardo:

    Parabéns, você conseguiu sintetizar algumas dicas excelentes e que funcionam em pouco código, coisa difícil de encontrar.

  6. Rodolfo:

    Ótimo tutorial!
    Quando comecei a mexer com j2me vi este artigo e foi de grande ajuda!
    Att, Rodolfo & javamovel.com

  7. Max DavisLins:

    Parabéns ótimo Post!

Deixe um comentário

blogarama.com Globe of Blogs EatonWeb Blog Directory