Aula 5
Gráficos
-
As classes de biblioteca utilizadas para elaborar a interface gráfica de um programa
formam o "Abstract Windowing Toolkit" e encontram-se
no pacote
java.awt
.
Uma classe essencial deste
pacote é a classe Graphics
que permite gerenciar
o contexto gráfico, i.e. o conjunto dos recursos
gráficos do computador. A classe Graphics
é uma
classe abstrata
(abstract
), pois embora os seus métodos são
definidos independentemente da plataforma, as suas implementações dependem do tipo
do computador que executa o programa. Para o programador, a consequência prática disto
é que esta classe não pode ser instanciada. Um objeto gráfico é criado automaticamente
pelo sistema e passado ao(s) método(s) encarregado(s) de "pintar" sobre a tela.
As classes capazes de (se) pintar sobre a tela são subclasses da classe
Component
. Por exemplo, a classe
Applet
é subclasse da classe
Panel
que, por sua vez, é subclasse da classe
Component
. A classe
Component
contem o método
paint
que recebe como argumento o objeto gráfico
criado pelo sistema. Este método deve ser sobre-escrito pelo programador
para realizar as operações de pintura desejadas:
public void paint( Graphics g )
{
// utiliza o objeto gráfico g para pintar
}
O método paint
não é chamado diretamente pelo
programador. É chamado automaticamente quando o computador exibe a componente sobre a tela
e também se acontecer um evento que exige que a componente seja repintada (por exemplo,
uma modificação do tamanho da janela na qual a componente está sendo mostrada). Caso o
programador quiser forçar uma repintagem da componente, ele chama o método
repaint
da mesma. Este método por sua vez induz
uma chamada ao método update
da componente.
O método update
recebe como argumento o objeto
gráfico e chama o método paint
, passando a este
o objeto gráfico. As assinaturas destes métodos são:
public void repaint( )
public void update( Graphics g )
O método repaint
não deve ser sobre-escrito pelo
programador pois realiza tarefas dependentes de máquina. Por "default", o método
update
prepara a repintagem limpando aquilo
que estava previamente pintado. Ele pode ser sobre-escrito, por exemplo para evitar esta
operação.
-
Cores são definidas e manipuladas utilizando-se a classe
Color
. Eis as maneiras de criar uma instância desta
classe:
Color cor1 = new Color( 120, 255, 30 );
// r, g, b int de 0 a 255
Color cor2 = new Color( 0.3, 0.0, 1.0 );
// r, g, b float de 0.0 a 1.0
Color cor3 = Color.red;
// cor padrão predefinida
A classe Graphics
possui métodos para informar qual
a cor que está sendo utilizada e para impor o uso de uma determinada cor:
public void paint( Graphics g )
{
Color cor1 = g.getColor(); // a cor utilizada até aqui
g.setColor( new Color( 20, 255, 130 ) ); // a cor a ser
utilizada a partir daqui
}
A classe Component
possui métodos para definir a
cor de fundo e a cor de frente. Estes métodos são particularmente úteis tratando-se de
componentes padrão:
Button botao = new Button( "Iniciar" );
botao.setBackground( new Color( 0.3, 0.2, 1.0 ) );
botao.setForeground( Color.pink );
-
Fontes são criadas e manipuladas utilizando-se a classe
Font
. O construtor desta classe possui a seguinte
assinatura:
public Font(
String s, // nome da fonte
int style, // estilo da fonte
int size ) // tamanho da fonte
O nome da fonte, por exemplo "Serif"
,
"SansSerif"
ou
"Monospaced"
,
é passado como uma cadeia de caráteres. O estilo da fonte (negrito ou não, itálico ou não)
é especificado usando-se variáveis inteiras estáticas
PLAIN, BOLD e
ITALIC, definidas na classe
Font
. Estas variáveis podem ser somadas. A unidade
para o tamanho da fonte é o ponto, que vale 1/72 de polegar. Exemplos de criação de
instâncias da classe Font
:
Font fonte1 = new Font( "SansSerif", Font.PLAIN, 14 );
Font fonte2 = new Font( "Monospaced", Font.BOLD + Font.ITALIC, 10 );
A classe Graphics
possui métodos para informar qual
a fonte que está sendo utilizada e para impor o uso de uma determinada fonte:
public void paint( Graphics g )
{
Font fonte1 = g.getFont(); // a fonte utilizada até aqui
g.setFont( new Font( "Serif", Font.BOLD, 16 ) );
// a fonte a ser utilizada
// a partir daqui
}
A classe Component
possui métodos para definir e
para descobrir a fonte usada para escrever texto nela. Estes métodos são particularmente
úteis tratando-se de componentes padrão que contêm algum texto, tais como botões e
campos de texto:
TextField campo = new TextField( "Ola" );
campo.setFont( new Font( "Serif", Font.BOLD, 16 ) );
Button botao = new Button( "Iniciar" );
Font fonte = campo.getFont();
botao.setFont( fonte );
A classe FontMetrics
é uma classe abstrata que
fornece informações sobre a métrica de fonte para a fonte utilizada pelo contexto
gráfico. Por exemplo, informa a largura de um determinado caráter, o quanto uma letra
pode de estender abaixo da linha de base, o avanço máximo na linha de um caráter para
o seguinte, etc. Consulte a documentação para detalhes. O contexto gráfico informa
qual a métrica de fonte relevante:
public void paint( Graphics g )
{
int avmax = g.getFontMetrics().getMaxAdvance(); // avanço máximo
...
}
-
A classe
Graphics
possui métodos para pintar na
tela texto e figuras geométricas. As coordenadas (x, y) utilizadas para definir o lugar
na tela onde a pintura deve ocorrer são números inteiros em pixel, medidos a partir
do canto esquerdo superior da componente. A abscissa x é medida horizontalmente (da
equerda para a direita) e a ordenada y é medida verticalmente (de cima para baixo).
No que diz respeito a texto, pode-se pintar cadeias de caráteres, listas de caráteres
e listas de bytes:
public void paint( Graphics g )
{
private String s = "Ola";
private char c[] = { 'M', 'u', 'n', 'd', 'o', '!' };
private byte b[] = { 'M', 'u', 'n', 'd', 'o', '!' };
g.setFont( new Font( "Serif", Font.BOLD, 16 ) );
g.drawString( s, 50, 30 ); // x = 50, y = 30
g.drawChars( c, 0, 5, 70, 50 ); // 5 elementos da lista, a partir do primeiro
g.drawBytes( b, 5, 1, 90, 80 ); // 1 elemento da lista, a partir do sexto
...
}
Componentes padrão utilizadas para apresentar texto na tela possuem métodos próprios
para tanto. Por exemplo, as classes TextField
e TextArea
herdam da classe
TexComponent
que possui um método
setText
:
TextField campo = new TextField( "Ola" ); // texto apresentado:
"Ola"
campo.setText( "Hi" ); // texto mudado para "Hi"
-
A classe
Graphics
possui métodos para pintar linhas,
retângulos, retângulos arredondados, círculos e ovais, arcos e polígonos. Estas figuras
podem ser mostradas como contornos ou figuras cheias. A seguir, exemplos de uso destes
métodos:
public void paint( Graphics g )
{
g.setColor( Color.blue );
g.drawLine( 10, 15, 50, 55 ); // linha de (10, 15) até (50, 55)
g.drawRect( 5, 10, 30, 20 ); // retângulo de largura 30 e altura 20
// com canto superior esquerdo em (5, 10)
g.fillRect( 50, 10, 30, 20 ); // retângulo cheio
g.clearRect( 60, 12, 10, 6 ); // furo retangular
g.drawRoundRect( 80, 10, 30, 20, 10, 5 ); // cantos arredondados são quartos
// de ovais de largura 10 e altura 5
g.fillRoundRect( 80, 60, 30, 40, 10, 5 ); // retângulo cheio arredondado
g.draw3DRect( 100, 20, 30, 40, true ); // retângulo cheio em relevo
g.draw3DRect( 100, 50, 30, 40, false ); // retângulo cheio afundado
g.setColor( Color.green ); // mudança de cor
g.drawOval( 150, 10, 30, 20 ); // oval contido num retângulo de largura 30
// e altura 20 com canto superior esquerdo
em (150, 10)
g.fillOval( 150, 400, 30, 20 ); // oval cheio
g.drawArc( 100, 200, 30, 20, -20, 70 ); // pedaço de um oval contido
// num retângulo de largura 30 e altura 20
// com canto superior esquerdo em (100, 200).
// O arco inicia no ângulo -20 graus e
// possui extensão angular de 70 graus
(convenção trigonométrica)
g.fillArc( 150, 400, 30, 20, 60, 60 ); // área cheia definida por um arco
// e seus raios
int x[] = {10, 30, 40, 25, 15 };
int y[] = {20, 10, 30, 50, 30 };
g.drawPolyline( x, y, 5); // linha juntando os 5 pontos
g.drawPolygon( x, y, 5); // contorno poligonal fechado definido pelos 5 pontos
g.fillPolygon( x, y, 5); // polígono cheio
Polygon poligono = new Polygon( x, y, 5 ); // objeto polígono
g.drawPolygon( poligono); // desenhar o polígono
poligono.addPoint( 10, 25 ); // acrescenta um ponto ao polígono
g.drawPolygon( poligono); // desenhar o novo polígono
}
A classe Graphics
possui dois modos de pintura. No
modo "default", objetos sobrepostos são simplesmente pintados um em cima do outro, mesmo
se forem da mesma cor. Um modo altenativo chamado modo XOR é disponível para evitar
que partes sobrepostas de objetos sejam pintadas da mesma cor:
public void paint( Graphics g )
{
g.setColor( Color.blue );
g.fillRect( 10, 10, 30, 30 ); // quadrado azul
g.fillArc( 20, 20, 30, 30, 0, 360 ); // círculo azul parcialmente sobreposto
// ao quadrado
g.setXORMode( Color.red ); // passar para o modo XOR
g.fillRect( 80, 80, 30, 30 ); // quadrado azul
g.fillArc( 90, 90, 30, 30, 0, 360 ); // círculo azul parcialmente sobreposto
// ao
quadrado. A parte sobreposta é pintada de vermelho
}