Neste artigo iremos introduzir um assunto muito interessante, o Java 2D. Nosso principal objeto é mostrar os conceitos básicos e exemplos fundamentais para que você possa estudar formas mais complexas. Antes de começar é preciso ter em mente que a matemática é fundamental para uso de tal recurso, pois você irá trabalhar principalmente com eixos cartesianos e outros conceitos matemáticos. Por exemplo, no caso do Java 3D já são necessários conhecimentos mais avançados na matemática, visto que você precisará trabalhar com angulação de objetos, azimuth, elevation e entre outros. Para quem já estudou Computação Gráfica não sentirá muito dificuldade, apenas irá relembrar conceitos já vistos.

Se você está começando agora com desenvolvimento gráfico, nada melhor do que começar pelo básico, o Java 2D. Ele oferecerá a você poderosos recursos para montar ambientes 2D muito bons e seus projetos. Obviamente que o trabalho é árduo sem ajuda de um “Engine” que monte tais objetos e controle nosso ambiente, mas nosso foco aqui não é ensinar ninguém a desenvolver jogos, e sim ensinar fundamentos no Java 2D.

Em que situação podemos aplicar o Java 2D, se não em jogos ? Em muitas situações simples, imagine, por exemplo, onde você precisa deixar um espaço livre para que o usuário possa desenhar, como num “Paint”, ou um exemplo onde você precisa criar formas geométricas como base nos eixos passados pelo usuário. Enfim, são muitas as situações em que o Java 2D faz-se presente, e nesse artigo mostraremos dois exemplos básicos: o desenho de uma reta e o desenho de outros objetos mais complexos.

Desenhando uma Reta

Em nossos exemplos, incluindo este, vamos utilizar Applets em Java para criar interfaces 2D, mas nada impede que você remova o Applet e use o Java 2D em um ambiente puramente Desktop, por exemplo. Optamos pelo Applet pela praticidade que ele nos oferece ao incorporar nossa aplicação à Web, de forma simples rápida.

Então vamos iniciar com o primeiro exemplo do desenho de uma reta na tela (Listagem 1).

Listagem 1. Desenhando a Reta – Comentado


  package forms;
   
  import java.applet.*;
  import java.awt.*;
   
  public class DesenhaReta extends Applet {
         
     int width, height;
   
     /*
      * Método init() do Applet, é análogo ao método main() de uma
      * classe Java Comum. Aqui colocamos os objetos e componentes que
      * desejamos inicializar
      * */
     public void init() {  
            
           //Capturamos a largura da janela
        width = getSize().width;
        
        //Capturamos a altura da janela
        height = getSize().height;
        
        //Configuramos o fundo da janela para ficar na cor preta.
        //Lembre-se que estamos trabalhando com Applet's, por isso
        //é possível usar métodos como "this.setBackground(Color.black);"
        setBackground( Color.black );
     }
   
     /*
      * Este é o principal método que realiza os "desenhos" na sua tela.
      * Toda vez que chamamos o "repaint()" este método é chamado, 
      * realizando o "redesenho" da sua janela.
      * */
     public void paint( Graphics g ) {
            
           /*
            * O objeto Graphics é que utilizaremos para desenhar na tela as mais
            * diversas formas geométricas. Então antes de desenhar qualquer coisa
            * vamos colocar dizer que o objeto desenhado deverá estar na cor 
            * "Verde/green".
            * */
        g.setColor( Color.green );
        
        /*
         * Criamos um laço for para desenhar as linhas/retas. 
         * Aqui já começa um pouco de matemática
         * básica, afinal o mundo de Softwares é pura matemática.
         *
         * O laço funciona da seguinte forma: A cada iteração 
         * desenhamos uma linha na tela nas
         * posições correspondentes as variáveis 'width' e 'height', 
         * ou seja, as posições das linhas
         * são relativas ao tamanho da tela.
         *
         * A forma mais fácil de entender o cálculo que foi realizado 
         * abaixo é desenhando um EIXO CARTESIANO em um papel, 
         * colocando as coordenadas e mapeando cada ponto x,y como
         * no código abaixo.
         * */
        for ( int i = 0; i < 10; ++i ) {
           g.drawLine( width, height, i * width / 10, 0 );
        }
     }
  }

Veja na Figura 1 como deve ser a saída do nosso Applet.

Figura 1. Java 2D – Desenho de Retas

Desenhando objetos mais complexos

Vamos complicar um pouco, desenhando objetos com mais pontos, como polígonos, por exemplo, que exigem um array de pontos para serem desenhados. Novamente fica a dica: se você deseja desenhar objetos com diversos pontos e muito complexo, como um “Nariz”, desenhe-o em um eixo cartesiano e mapeie os pontos desejados, caso contrário, você ficará horas na tentativa e erro até encontrar o ponto exato.

Listagem 2. Diversos objetos


  package forms;
   
  import java.applet.*;
  import java.awt.*;
   
  public class DesenhaOutrosObjetos extends Applet {
   
     int width, height;
   
     public void init() {
        width = getSize().width;
        height = getSize().height;
        setBackground( Color.black );
     }
   
     public void paint( Graphics g ) {
   
        g.setColor( Color.red );
        g.drawRect( 10, 20, 100, 15 );
        g.setColor( Color.pink );
        g.fillRect( 240, 160, 40, 110 );
   
        g.setColor( Color.blue );
        g.drawOval( 50, 225, 100, 50 );
        g.setColor( Color.orange );
        g.fillOval( 225, 37, 50, 25 );
   
        g.setColor( Color.yellow );
        g.drawArc( 10, 110, 80, 80, 90, 180 );
        g.setColor( Color.cyan );
        g.fillArc( 140, 40, 120, 120, 90, 45 );
   
        g.setColor( Color.magenta );
        g.fillArc( 150, 150, 100, 100, 90, 90 );
        g.setColor( Color.black );
        g.fillArc( 160, 160, 80, 80, 90, 90 );
   
        g.setColor( Color.green );
        g.drawString( "Meu Texto", 50, 150 );
     }
  }

Veja a quantidade de objetos que temos desenhado em nosso Applet. Vamos dispensar comentários detalhados desse método, pois ele segue o mesmo padrão da Listagem 1, apenas acrescentando mais objetos. Mas fique atento ao seguinte: Todos são desenhados através de coordenadas no eixo cartesiano. O método “fillX” (fillArc, fillOval, fillRect..) irá preencher seu objeto com alguma cor, mas note que devemos usar o “g.setColor()” antes de usar o “g.fillX()”, pois estamos dizendo que o estado atual do objeto “Graphics” está na cor que você determinou. Assim, tudo que ele fizer será considerando esta cor.

Por fim, e não menos importante, vamos desenhar um polígono com diversos pontos. Antes de criar este desenho, foi feito um mapeamento completo do objeto em um eixo cartesiano. Criamos um polígono para cada região específica do nosso “polígono maior”, assim podemos monitorar cada região, verificando, por exemplo, se o usuário clicou dentro de determinada região (Listagem 3).

Listagem 3. Criando um Polígono Completo


  package forms;
   
  import java.applet.Applet;
  import java.awt.Graphics;
  import java.awt.Polygon;
   
  public class Poligono2D extends Applet {
   
           /**
            *
            */
           private static final long serialVersionUID = 1L;
   
           int pontoXInicial = 30;
           int pontoYInicial = 100;
   
           int distanciaX = 15 + 30;
           int distanciaY = 25 + 30;
           int larguraQuadradoInterno = 12;
   
           int[] x = { pontoXInicial, pontoXInicial + distanciaX,
                          pontoXInicial + distanciaX, pontoXInicial };
           int[] y = { pontoYInicial, pontoYInicial,
                          pontoYInicial - distanciaY,
                          pontoYInicial - distanciaY };
   
           int[] x1 = { x[0] + larguraQuadradoInterno, x[1] –
              larguraQuadradoInterno, x[2] - larguraQuadradoInterno,
                              x[3] + larguraQuadradoInterno };
           int[] y1 = { y[0] - larguraQuadradoInterno, y[1] – 
              larguraQuadradoInterno, y[2] + larguraQuadradoInterno,
                              y[3] + larguraQuadradoInterno };
   
           int[] x2 = { x[3], x1[3], x1[2], x[2] };
           int[] y2 = { y[3], y1[3], y1[2], y[2] };
           
           int[] x3 = { x[0], x[1], x1[1], x1[0] };
           int[] y3 = { y[0], y[1], y1[1], y1[0] };
           
           int[] x4 = { x[1], x1[1], x1[2], x[2] };
           int[] y4 = { y[1], y1[1], y1[2], y[2] };
           
           int[] x5 = { x[0], x1[0], x1[3], x[3] };
           int[] y5 = { y[0], y1[0], y1[3], y[3] };
   
           Polygon quadrado = new Polygon(x, y, 4);
           Polygon face1 = new Polygon(x1, y1, 4);
           Polygon face2 = new Polygon(x2, y2, 4);
           Polygon face3 = new Polygon(x3, y3, 4);
           
           Polygon face4 = new Polygon(x4, y4, 4);
           Polygon face5 = new Polygon(x5, y5, 4);
   
           @Override
           public void init() {
                     this.setSize(300, 300);
           }
   
           @Override
           public void paint(Graphics g) {
                     super.paint(g);
                     g.drawPolygon(quadrado);
                     g.drawPolygon(face1);
                     g.drawPolygon(face2);
                     g.drawPolygon(face3);
                     g.drawPolygon(face4);
                     g.drawPolygon(face5);
                     g.drawString("100",x1[0], y[0]+15);
           }
   
  }

Nosso exemplo acima está todo parametrizado, ou seja, se mudarmos a variável “larguraQuadradoInterno” então a distância do quadrado interno irá aumentar ou diminuir do quadrado externo, assim como os pontos X inicial e Y inicial que determinam onde nosso polígono deve ser desenhado.

Dado os exemplos acima, você pode utilizar a criatividade e base matemática para melhor os objetos e criar exemplos ainda mais realistas. Vale a pena aprofundar-se em tal assunto, que pode ser aplicado em diversos projetos.