Uma visão rápida sobre o Java 2D

Propaganda
Uma visão rápida sobre o Java 2D
Escrito por Vinícius Godoy de Mendonça - Última atualização Seg, 26 de Outubro de 2009 10:38
O Java 2D é uma API extensa e poderosa. Ele faz parte do JDK padrão, e inclui diversos tipos
de funções para desenhar diretamente na tela, desenhar texto, manipular imagens e utilizar a
impressora. Nesse artigo, vamos conhecer um pouco da terminologia básica do Java 2D, e ver
de maneira resumida suas funcionalidades.
Introdução
O Java 2D é implementado como uma extensão do Abstract Window Toolkit (AWT). Ele
tornou-se muito poderoso depois da adição de outra extensão: o Swing. Inicialmente, os
projetistas da AWT delegavam a tarefa de desenhar janelas, botões e caixas de texto ao
sistema operacional. Mas logo perceberam que isso não era muito portável, e limitava
severamente a performance do Java em aplicações mais sérias. Então, decidiram associar a
AWT uma nova extensão, chamada Swing, que desenharia integralmente todos os
componentes de tela. Ao fazer isso, a biblioteca Java 2D ganhou grande importância.
O Swing rapidamente tornou-se o padrão do Java para todo o tipo de aplicação desktop.
Entretanto, uma de suas grandes reclamações sempre foi a performance, o que motivou os
desenvolvedores da Sun a investir em otimizações agressivas no Java 2D. Entre elas, está a
aceleração de hardware (integrada com OpenGL), possibilidade de trabalhar em modo janela
exclusivo (FSEM), otimizações agressivas na biblioteca de manipulação de imagens, entre
outras coisas.
Dentre as principais capacidades do Java 2D, podemos citar:
- Um modelo uniforme de desenho para dispositivos de vídeo e impressoras;
- Um grande número de primitivas geométricas (retângulos, elipses, curvas), e um
mecanismo para se desenhar qualquer forma geométrica;
- Mecanismos para detectar colisão em texto e imagens;
- Modelos de composição (Alpha Composition), que permitem escolher como combinar
imagens que se interceptam;
- Modelo de cores avançado;
- Diretivas para controlar a qualidade do desenho;
- Classes para manipulação uniforme dos principais formatos de imagem;
Desenho com Java 2D
1/7
Uma visão rápida sobre o Java 2D
Escrito por Vinícius Godoy de Mendonça - Última atualização Seg, 26 de Outubro de 2009 10:38
Espaço de coordenadas
O Java 2D permite o trabalho em dois tipos de sistemas de coordenadas. As coordenadas do
dispositivo e as coordenadas de usuário. As coordenadas do dispositivo se referem ao sistema
do hardware que está sendo trabalhado. Vão alterar de acordo com a resolução de tela, ou o
tamanho da folha, por exemplo.
Já as coordenadas do usuário são um sistema lógico, usado pelo seu programa. Elas são
uniformes e independentes de dispositivo, é o próprio Java 2D que se encarrega da conversão
de um sistema para outro.
O sistema de coordenadas da aplicação inicialmente considera a coordenada (0,0) como o
canto superior esquerdo da área de desenho. As coordenadas serão sempre crescentes, com x
crescendo para direita e y para baixo. Na realidade, o Java 2D permite que essas coordenadas
sejam alteradas à vontade, permitindo a criação de diversos sistemas coordenados próprios,
dentro da aplicação.
O contexto gráfico
2/7
Uma visão rápida sobre o Java 2D
Escrito por Vinícius Godoy de Mendonça - Última atualização Seg, 26 de Outubro de 2009 10:38
Todo desenho no Java 2D é feito através da classe Graphics2D . Essa classe. que deriva da
classe
Graphics , representa
o contexto gráfico sobre o qual o desenho será feito. Por isso, a classe guarda informações
como cor será aplicada sobre a pintura, que tipo de borda o desenho terá ou qual será a fonte
utilizada no texto, entre outras coisas.
Normalmente, uma aplicação é formada não por uma só imagem, mas por várias. Seria
extremamente trabalhoso garantir que uma alteração no feita em uma imagem não interferisse
em outra. Por exemplo, ao desenhar o fantasminha azul acima, você poderia definir no
Graphics que ele deveria usar 80% de transparência. Entretanto, se você esquecer de desfazer
essa definição, o pacman, que será desenhado logo em seguida, poderia ficar transparente
também. Para contornar esse problema, os projetistas do Java 2D criaram uma forma de copiar
o contexto gráfico. Isso permite que você trabalhe sobre uma cópia, faça as modificações
necessárias para pintar a imagem, e descarte essa cópia ao final da pintura, deixando o
contexto gráfico original inalterado.
/** Método paint do fantasma */ public void paint(Graphics g) { //1. Copiamos o contexto
gráfico Graphics2D g2d = (Graphics2D) g.create();
//2. Desenhamos o fantasma 80%
transparente AlphaComposite alpha =
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8); g2d.setComposite(alpha);
g2d.drawImage(x, y, phantomImage, null);
//3. Descartamos a cópia do contexto gráfico
g2d.dispose(); }
Uma confusão comum feita pelos iniciantes em Java 2D é pensar que a classe Graphics
representa a superfície de desenho em si. Isso não é verdade. Ela só representa o estado
exato em que será feita a pintura. Por isso, copiar esse contexto como sugerido acima é uma
operação extremamente eficiente e barata. Assim como descarta-lo ao final da pintura não
destruirá o desenho. De fato, isso nos leva a primeira regra de ouro ao desenhar em Java 2D:
“Jamais altere o estado do objeto Graphics recebido como parâmetro nas funções de pintura”.
Caso contrário, o Swing poderá usar esse objeto na hora de desenhar partes de sua janela, e
você poderá obter efeitos muito estranhos, diferentes do esperado e difíceis de corrigir.
Dentre os estados no interior da classe Graphics2D, podemos citar:
3/7
Uma visão rápida sobre o Java 2D
Escrito por Vinícius Godoy de Mendonça - Última atualização Seg, 26 de Outubro de 2009 10:38
- A largura que as bordas de uma figura são desenhadas (Pen, Stroke);
- Como duas bordas se conectam;
- A área, não necessariamente retangular, em que o desenho será realizado (Clipping
path);
- Transformações de translação, rotação, escala e shear (AffineTransform);
- Cores e padrões de pintura;
- Composições entre múltiplos objetos (Composite);
Entretanto, a classe Graphics2D não guarda somente estados, mas também provê métodos
para realizar a pintura em si. E isso nos leva ao próximo tópico.
Primitivas geométricas
As primitivas geométricas do Java 2D são: pontos, linhas, retângulos, arcos e elipses e curvas.
As classes que lidam com cada uma dessas geometrias são definidas no pacote java.awt.geo
m
. Por
questões de performance e conveniência, o objeto Graphics também fornece métodos para a
pintura direta dessas primitivas, sem a necessidade de criação de um objeto. Além dessas, o
Java 2D fornece uma classe chamada
GeneralPath
, que permite a criação de formas arbitrárias, baseadas em linhas e curvas de Bézier.
4/7
Uma visão rápida sobre o Java 2D
Escrito por Vinícius Godoy de Mendonça - Última atualização Seg, 26 de Outubro de 2009 10:38
As classes
entre
determinada
comuns
dois
como
pontos
deforma,
primitivas
interseção
(Point2D),
etc. O
também
ou
Java
área
subtração
ainda
fornecem
de figuras
fornece
de duas
diversos
sólidas,
a formas.
classe
métodos
teste
Area,
se um
que
bastante
ponto
permite
práticos,
está
realizar
contido
como
operações
emdistância
uma
Texto
O Java 2D fornece diversas classes para trabalhar com texto. Embora a forma mais direta e
mais comumente usada seja simplesmente chamar os métodos setFont e drawString da classe
Graphics, a API fornece classes auxiliares, que facilitam recursos mais avançados, como o
posicionamento do texto. Essas classes, são parte do pacote java.awt.Font .
Chamamos de Glyph a forma usada para representar um caractere dentro de uma fonte. Um
caractere de texto real pode ser formado por uma combinação de dois glyphs, como é o caso
da maior parte das letras acentuadas. Da mesma forma, podem haver Glyphs que representam
o desenho de mais de um caractere, como esse aqui o do símbolo de peseta: ₧
Uma fonte, é portanto, um conjunto de Glyphs, com o mesmo estilo artístico. Essa fonte pode
ter uma série de variações, como itálico ou negrito, e essas variações são chamadas de faces.
5/7
Uma visão rápida sobre o Java 2D
Escrito por Vinícius Godoy de Mendonça - Última atualização Seg, 26 de Outubro de 2009 10:38
O conjunto de todas as faces de uma fonte é chamada de
família
. Podemos questionar o Java sobre diversas propriedades da fonte em questão, tais como
altura, largura e outras métricas. Essas propriedades são encapsuladas na classe
FontMetrics
.
Antes do texto ser exibido, entretanto, ele deve ser formatado. Quem realiza essa tarefa é a
classe TextLayout . Ela fornece métodos para lidar com fontes misturadas, idiomas diferentes
e texto bidirecional. Caso você queira um controle ainda mais refinado sobre as opções de
layout, o Java 2D fornece uma classe de mais baixo nível, chamada
Glyph
Vector
.
Imagens
Por último, mas não menos importante, o Java 2D fornece diversos recursos para a
manipulação de imagens. O primeiro recurso interessante é certamente uma classe que
permite a carga e escrita de diversos tipos de imagem de maneira uniforme, chamada ImageI
O
.
As imagens representadas pela classe BufferedImage . Um dos recursos mais interessantes
do Java 2D, é que podemos requisitar o objeto Graphics de qualquer imagem, e realizar pintura
ou escrever texto sobre imagens da mesma forma que fazemos para desenhar os
componentes de tela.
O Java ainda suporta filtros sobre imagens, através da classe BufferedImageOp . Alguns sites
de terceiros, como o
jhlabs
, já tem diversos desses filtros implementados, o que pode adicionar efeitos bastante
interessantes aos jogos.
Por fim, o Java permite ainda a manipulação direta e eficiente dos pixels de uma imagem,
através de suas definições, contidas na classe Raster . Essa manipulação avançada é
geralmente necessária apenas para quem vai trabalhar com aplicações que geram filtros
diretamente e, se esse é o seu caso, pode ser interessante consultar o tutorial
6/7
Uma visão rápida sobre o Java 2D
Escrito por Vinícius Godoy de Mendonça - Última atualização Seg, 26 de Outubro de 2009 10:38
“Using Rasters for Image Processing”, do Java Boutique
. Fique atento, pois o tutorial também tem uma
segunda parte
.
Infelizmente, a biblioteca Java2D cobre bem apenas imagens formadas por mapas de bits.
Para imagens vetoriais, é necessário utilizar bibliotecas de terceiros.
Conclusões
Nesse artigo, vimos rapidamente os recursos do Java 2D, e conhecemos a terminologia básica
da maior parte de seus componentes. Deixamos de fora somente a parte de impressão, menos
importante para jogos. Embora ainda não possamos desenhar nada, já podemos ter uma boa
noção do quão poderosa a biblioteca é. Mais importante, aprendemos a terminologia do Java
2D, associada ao nome de diversas de suas principais classes.
7/7
Download