J2ME/Lições/Canvas

< J2ME‎ | Lições

Durante as primeiras lições trabalhamos com a chamada "interface de alto nível", ou seja, aplicávamos os comandos para a interface pré construída no celular executa-las, agora iremos começar a trabalhar com a chamada "interface de baixo nível", ou seja, iremos dar os comandos diretamente para os gráficos, trabalhando com a manipulação de pixels. Para isso iremos usar amplamente a classe Canvas.

Estrutura CanvasEditar

Primeiramente precisamos criar uma classe exclusiva separada da classe principal para trabalhar com o Canvas, essa também será importada do pacote javax.microedition.lcdui, e irá estender a classe Canvas.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
}

Agora devemos colocar o método paint() que entra como parâmetro um objeto da classe Graphics que irá controlar o que irá ser exibido no canvas.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    public void paint(Graphics meuGrafico){
    }
}

Agora na classe principal, a chamada do objeto da ClasseMeuCanvas é feita do mesmo modo das chamadas dos outros objetos, através de um método do objeto Display, vejamos abaixo o conteúdo dos 2 arquivos, o ClasseMeuCanvas.java e o ClassePrincipal.java.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    public void paint(Graphics meuGrafico){
    }
}
//arquivo ClassePrincipal.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class ClassePrincipal extends MIDlet {
    Display meuDisplay = Display.getDisplay(this);
    ClasseMeuCanvas meuCanvas = new ClasseMeuCanvas();
    
    public void startApp() {
        meuDisplay.setCurrent(meuCanvas);
    }
    public void pauseApp() {
    }
    public void destroyApp(boolean unconditional) {
    }
}

Desenhando objetos primitivosEditar

Agora que já sabemos a estrutura de um canvas, vamos desenhar algo na tela, para isso iremos usar o objeto do tipo Graphics e aplicar sobre ele métodos pré-fabricados pelo J2ME que irão desenhar coisas simples na tela como strings, retângulos, arcos, triângulos, etc. Esses comandos ficarão dentro do método paint().

Desenhando uma linhaEditar

Vamos desenhar uma linha simples, vamos usar o método drawLine() da classe Graphics, ele irá receber 4 atributos: o 1ª será o pixel x de onde a linha vai começar, o 2º será o pixel y de onde a linha vai começar, o 3º o pixel x onde a linha vai terminar, o 4º será o pixel y onde a linha vai terminar.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    public void paint(Graphics meuGrafico){
        meuGrafico.drawLine(30, 40, 70, 90);
    }
}

Desenhando um retânguloEditar

Vamos desenhar um retângulo, vamos usar o método drawRect() da classe Graphics, ele irá receber 4 atributos: o 1ª será o pixel x de onde o retângulo vai começar, o 2º será o pixel y de onde o retângulo vai começar, o 3º será a largura em pixels do retângulo, o 4º será a altura em pixels do retângulo.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    public void paint(Graphics meuGrafico){
        meuGrafico.drawRect(20, 30, 60, 70);
    }
}

Desenhando um retângulo cheioEditar

Você viu anteriormente como desenhar um retângulo na tela, só que no exemplo anterior esse retângulo era oco por dentro, ou seja, você só desenhou as bordas do retângulo, vamos agora fazer um retângulo totalmente pintado por dentro, para isso vamos usar o método fillRect() da classe Graphics, ele irá receber os mesmos atributos do método drawRect(): o 1ª será o pixel x de onde o retângulo vai começar, o 2º será o pixel y de onde o retângulo vai começar, o 3º será a largura em pixels do retângulo, o 4º será a altura em pixels do retângulo.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    public void paint(Graphics meuGrafico){
        meuGrafico.fillRect(20, 30, 50, 60);
    }
}

Desenhando uma StringEditar

Vamos desenhar uma string, note que não vamos simplesmente colocar a string na tela, vamos desenhá-la, apesar disso o J2ME já vem com uma fonte string padrão para o Canvas. Vamos usar o método drawString() da classe Graphics, ele irá receber 4 atributos: o 1º será o texto da string, o 2º será o pixel x de onde vai ser desenhado, o 3º será o pixel y de onde vai ser desenhado, o 4º será a "raiz" do objeto, ou seja, onde será a referência dos pixels x e y.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    public void paint(Graphics meuGrafico){
        meuGrafico.drawString("Texto da string", 50, 100, Graphics.LEFT|Graphics.TOP);
    }
}

Nesse caso a raiz do pixel x está no ponto esquerdo do objeto (Graphics.LEFT), e a raiz do pixel y está no ponto acima do objeto (Graphics.TOP). Você também pode colocar a raiz do pixel x na direita (Graphics.RIGHT) ou no centro (Graphics.HCENTER), e a raiz do pixel y na parte de baixo (Graphics.BOTTOM) ou no centro (Graphics.VCENTER).

Colocando uma corEditar

Você pode setar cores para desenhar objetos com cores diferentes, para isso use o método setColor() da classe Graphics entrando como parâmetro os valores das cores vermelho, verde e azul respectivamente.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    public void paint(Graphics meuGrafico){
        meuGrafico.setColor(255, 0, 0);
        meuGrafico.drawRect(50, 50, 20, 30);
    }
}

Pegando uma corEditar

Para pegar uma cor vamos utilizar o método getColor() da classe Graphics que irá retornar um inteiro com os valores RGB agrupados.

Primeiro vamos criar a variável inteira que irá armazenar a cor.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    int corPega;
    public void paint(Graphics meuGrafico){
    }
}

Agora vamos setar alguma cor através do método setColor().

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    int corPega;
    public void paint(Graphics meuGrafico){
        meuGrafico.setColor(255, 128, 64);
    }
}

Agora vamos utilizar o método getColor(), e armazenar o resultado na variável corPega.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    int corPega;
    public void paint(Graphics meuGrafico){
        meuGrafico.setColor(255, 128, 64);
        corPega = meuGrafico.getColor();
    }
}

O valor obtido na variável corPega é equivalente ao número hexadecimal agrupado FF, 80, 40 que se traduz em inteiro como 255, 128, 64.

Desenhando uma imagemEditar

Vimos anteriormente as primitivas que o J2ME nos oferece, agora vamos mostrar na tela uma imagem feita por nós mesmo. Primeiro crie a sua imagem em algum editor externo a sua escolha, salve a imagem e coloque no mesmo diretório onde se localiza o arquivo ClasseMeuCanvas.java.

Agora primeiramente vamos incluir o pacote java.io que contém o tratamento de exceção.

//arquivo ClasseMeuCanvas.java
import java.io.*;
import javax.microedition.lcdui.*;

Agora criar uma variável da classe Image.

//arquivo ClasseMeuCanvas.java
import java.io.*;
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    Image minhaImagem;
    public void paint(Graphics meuGrafico){
    }
}

Agora vamos usar o construtor para inicializar o objeto minhaImagem. Para isso vamos jogar a exceção.

//arquivo ClasseMeuCanvas.java
import java.io.*;
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    Image minhaImagem;
    
    ClasseMeuCanvas throws Exception {
    }
    public void paint(Graphics meuGrafico){
    }
}

Agora dentro do construtor vamos inicializar o objeto minhaImagem utilizando o método createImage() da classe Image, ele receberá como parâmetro o endereço da imagem que você criou.

//arquivo ClasseMeuCanvas.java
import java.io.*;
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    Image minhaImagem;
    
    ClasseMeuCanvas throws Exception {
        minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
    }
    public void paint(Graphics meuGrafico){
    }
}

Agora dentro do método paint() vamos botar a nossa imagem para ser exibida, utilizando o método drawImage() da classe Graphics, como parâmetro ele irá receber 4 atributos: o 1ª será o nome da variável da classe Image, o 2º será o pixel x de onde vai ser desenhado, o 3º será o pixel y de onde vai ser desenhado, o 4º será a "raiz" do objeto, ou seja, onde será a referência dos pixels x e y.

//arquivo ClasseMeuCanvas.java
import java.io.*;
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    Image minhaImagem;
    
    ClasseMeuCanvas throws Exception {
        minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
    }
    public void paint(Graphics meuGrafico){
        meuGrafico.drawImage(minhaImagem, 30, 40, Graphics.LEFT|Graphics.TOP);
    }
}

Criando uma atualização de telaEditar

Vimos como colocar objetos na tela através de um comando, agora vamos ver como se cria uma atualização de tela, para isso dentro do método paint() iremos usar o método repaint() que irá funcionar como um "retornador" para o método paint() ser executado novamente. Para isso vamos primeiro criar uma variável inteira i na ClasseMeuCanvas e vamos inicia-la com o valor 0.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    int i=0;
    public void paint(Graphics meuGrafico){
    }
}

Agora vamos desenhar um simples retângulo na tela, vamos usar como os primeiros atributos a variável i que criamos (que no caso vale 0).

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    int i=0;
    public void paint(Graphics meuGrafico){
        meuGrafico.drawRect(i, i, 100, 100);
    }
}

Vamos agora dar um incremento no i, para sempre que se retornar ao paint() seu valor ser acrescido de +1.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    int i=0;
    public void paint(Graphics meuGrafico){
        meuGrafico.drawRect(i, i, 100, 100);
        i++;
    }
}

Vamos agora finalmente aplicar o método repaint() dentro do método paint(), e ver a movimentação do nosso retângulo na tela. Vamos mostrar abaixo o código completo.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    int i=0;
    public void paint(Graphics meuGrafico){
        meuGrafico.drawRect(i, i, 100, 100);
        i++;
        repaint();
    }
}

ComandosEditar

Vamos entrar agora na parte de entrada de comandos através das teclas do celular, primeiramente a classe Canvas tem 3 métodos pré-definidos para isso, são o keyPressed() para quando se aperta a tecla do celular, keyRepeated() para quando se segura a tecla do celular e keyReleased() para quando se solta a tecla do celular.

Primeiramente para usá-lo vamos fazer a chamada do método fora do médodo paint(), o método deverá ser do tipo protected.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    protected void keyPressed(int getTecla){
    }
    
    public void paint(Graphics meuGrafico){
        repaint();
    }
}

Agora vamos definir uma ação para o caso de o usuário apertar a tecla que queremos, no caso vamos escolher a tecla 1 do celular, vamos colocar um if dentro do método keyPressed(). Você pode comparar com as constantes KEY_NUM1, KEY_NUM2, ..., KEY_STAR, KEY_POUND.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    protected void keyPressed(int getTecla){
        if (getTecla == KEY_NUM1);
    }
    
    public void paint(Graphics meuGrafico){
        repaint();
    }
}

Agora vamos colocar uma ação para quando pressionarmos a tecla, nesse caso vamos exibir uma mensagem no console.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    protected void keyPressed(int getTecla){
        if (getTecla == KEY_NUM1){
            System.out.println("Pressionou tecla 1 do celular");
        }
    }
    
    public void paint(Graphics meuGrafico){
        repaint();
    }
}

Você pode usar o mesmo processo apenas trocando método keyPressed() por keyRepeated() ou keyReleased().

Comandos de jogoEditar

Vimos como obter as teclas do teclado padrão do celular (apenas os números e as teclas * e #), agora vamos ver como pegar as teclas auxiliares.

Primeiramente vamos usar o mesmo método keyPressed(), keyRepeated() ou keyReleased() do módulo anterior.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    protected void keyPressed(int getTecla){
    }
    
    public void paint(Graphics meuGrafico){
        repaint();
    }
}

Agora as constantes das teclas auxiliares não podem ser pegas de forma direta, para isso vamos usar o método getKeyCode() e como parâmetro vamos entrar o código da tecla que queremos, nesse caso usamos a tecla FIRE que fica no meio das setas do celular.

//arquivo ClasseMeuCanvas.java
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends Canvas {
    protected void keyPressed(int getTecla){
        if (getTecla == getKeyCode(FIRE));
    }
    
    public void paint(Graphics meuGrafico){
        repaint();
    }
}

Agora vamos colocar uma ação para quando pressionarmos a tecla, nesse caso vamos exibir uma mensagem no console.

public class ClasseMeuCanvas extends Canvas {
    protected void keyPressed(int getTecla){
        if (getTecla == getKeyCode(FIRE)){
            System.out.println("Pressionou tecla FIRE do celular");
        }
    }
    
    public void paint(Graphics meuGrafico){
        repaint();
    }
}