• Nenhum resultado encontrado

2.13 Elipses, linhas, texto e cores

Na Seção 2.12, você aprendeu a escrever um programa que desenha retângulos. Nesta seção, você aprenderá a desenhar outras formas: elipses e linhas. Com esses elementos gráfi cos, você pode desenhar muitas fi guras interessantes.

Para desenhar uma elipse, você especifi ca a caixa delimitadora (veja Figura 23) da mesma maneira como você especifi caria um retângulo, a saber, pelas coordenadas x e y do canto superior esquerdo e pela largura e altura da caixa.

(x, y)

Altur

a

Largura

Entretanto, nenhuma classe Ellipse simples está disponível para que você possa utilizar. Em vez disso, você deve utilizar uma das duas classes Ellipse2D.Float e Ellipse2D.Double, dependendo se você quer armazenar as coordenadas da elipse como valores de ponto fl utuan- te de precisão simples ou dupla. Como os últimos são mais convenientes de utilizar em Java, sempre utilizaremos a classe Ellipse2D.Double. Eis como você constrói uma elipse:

Ellipse2D.Double ellipse = new Ellipse2D.Double(x, y, width, height);

O nome da classe Ellipse2D.Double parece diferente dos nomes de classe que vimos até agora. Ele consiste em dois nomes de classe Ellipse2D e Double separados por um ponto (.). Isso indica que Ellipse2D.Double é uma classe interna, dentro de Ellipse2D. Ao construir e utilizar elipses, na verdade você não precisa se preocu- par com o fato de que Ellipse2D.Double é uma classe interna – simplesmente pense nela como uma classe com um nome longo. Mas, na instrução import na parte superior do seu programa, você deve ter cuidado em importar apenas a classe externa:

import java.awt.geom.Ellipse2D;

Desenhar uma elipse é fácil: utilize exatamente o mesmo método draw da classe Gra- phics2D que você utilizou para desenhar os retângulos.

g2.draw(ellipse);

Para desenhar um círculo, simplesmente confi gure a largura e a altura com os mesmos valores:

Ellipse2D.Double circle = new Ellipse2D.Double(x, y, diameter, diameter); g2.draw(circle);

Observe que (x, y) é o canto superior esquerdo da caixa delimitadora, não o centro do círculo.

Para desenhar uma linha, utilize um objeto da classe Line2D.Double. Uma linha é construída especifi cando-se seus dois pontos fi nais. Você pode fazer isso de duas manei- ras. Simplesmente forneça as coordenadas x e y dos dois pontos fi nais:

Line2D.Double segment = new Line2D.Double(x1, y1, x2, y2); Ou especifi que cada ponto fi nal como um objeto da classe Point2D.Double:

Point2D.Double from = new Point2D.Double(x1, y1); Point2D.Double to = new Point2D.Double(x2, y2); Line2D.Double segment = new Line2D.Double(from, to);

A segunda opção é mais orientada a objetos e costuma ser mais útil, especialmente se os objetos ponto puderem ser reutilizados em outra parte no mesmo desenho.

Ellipse2D.Double e

Line2D.Double são classes que descrevem formas gráfi cas.

Linha de base

Ponto de base

Na maioria das vezes, queremos colocar texto dentro de um desenho, por exemplo, rotular alguns elementos. Utilize o método drawString da classe Graphics2D para desenhar uma string em qualquer lugar de uma janela. Você deve especifi car a string e as coordenadas x e y do ponto de base do primeiro caractere na string (veja Figura 24). Por exemplo,

g2.drawString("Message", 50, 100);

2.13.1 CORES

Quando você começa a desenhar pela primeira vez, todas as formas e strings são dese- nhadas com uma caneta preta. Para alterar essa cor, você precisa fazer uso de um objeto do tipo Color. Java usa o modelo de cores RGB. Isto é, você especifi ca uma cor de acordo com os valores das cores primárias – vermelho, verde e azul – que compõem a cor. Os valores são fornecidos como inteiros entre 0 (ausência de cor primária) e 255 (valor má- ximo presente). Por exemplo,

Color magenta = new Color(255, 0, 255);

constrói um objeto Color com vermelho máximo, nenhum verde e azul máximo, produ- zindo uma cor roxa brilhante chamada magenta.

Para sua conveniência, uma variedade de cores foi predefi nida na classe Color. A Tabela 1 mostra essas cores predefi nidas e seus valores RGB. Por exemplo, Color.PINK foi predefi nida como sendo a mesma cor de newColor(255, 175, 175).

Para desenhar um retângulo com uma cor diferente, primeiro confi gure a cor do objeto Graphics2D e então chame o método draw: g2.setColor(Color.RED);

g2.draw(circle); // desenha a forma em vermelho

O método drawString

desenha uma string, iniciando no seu ponto de base.

Quando você confi gura uma nova cor no contexto gráfi co, ela é utilizada para as operações de desenho subseqüentes.

Tabela 1 Cores predefi nidas e seus valores RGB

Cor Valor RGB Color.BLACK 0, 0, 0 Color.BLUE 0, 0, 255 Color.CYAN 0, 255, 255 Color.GRAY 128, 128, 128 Color.DARKGRAY 64, 64, 64 Color.LIGHTGRAY 192, 192, 192 Color.GREEN 0, 255, 0 Color.MAGENTA 255, 0, 255 Color.ORANGE 255, 200, 0 Color.PINK 255, 175, 175 Color.RED 255, 0, 0 Color.WHITE 255, 255, 255 Color.YELLOW 255, 255, 0

Se quiser colorir o interior da forma, utilize o método fi ll em vez do método draw. Por exemplo,

g2.fi ll(circle);

preenche o interior do círculo com a cor atual.

O programa a seguir coloca todas essas formas em funcionamento, criando um dese- nho simples (veja Figura 25).

ch02/faceviewer/FaceComponent.java

1 import java.awt.Color; 2 import java.awt.Graphics; 3 import java.awt.Graphics2D; 4 import java.awt.Rectangle; 5 import java.awt.geom.Ellipse2D; 6 import java.awt.geom.Line2D; 7 import javax.swing.JPanel; 8 import javax.swing.JComponent; 9 10 /**

11 Um componente que desenha o rosto de um alienígena.

12 */

13 public class FaceComponent extends JComponent 14 {

15 public void paintComponent(Graphics g) 16 {

17 // Recupera Graphics2D

18 Graphics2D g2 = (Graphics2D) g; 19

20 // Desenha a cabeça

21 Ellipse2D.Double head = new Ellipse2D.Double(5, 10, 100, 150); 22 g2.draw(head);

23

24 // Desenha os olhos

25 Line2D.Double eye1 = new Line2D.Double(25, 70, 45, 90); 26 g2.draw(eye1);

27

28 Line2D.Double eye2 = new Line2D.Double(85, 70, 65, 90); 29 g2.draw(eye2);

30

31 // Desenha a boca

32 Rectangle mouth = new Rectangle(30, 130, 50, 5); 33 g2.setColor(Color.RED);

34 g2.fi ll(mouth); 35

36 // Desenha a saudação

37 g2.setColor(Color.BLUE);

38 g2.drawString("Hello, World!", 5, 175); 39 }

ch02/faceviewer/FaceViewer.java

1 import javax.swing.JFrame; 2

3 public class FaceViewer 4 {

5 public static void main(String[] args) 6 {

7 JFrame frame = new JFrame(); 8 frame.setSize(300, 400);

9 frame.setTitle("An Alien Face");

10 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 11

12 FaceComponent component = new FaceComponent(); 13 frame.add(component); 14 15 frame.setVisible(true); 16 } 17 } AUTOVERIFICAÇÃODAAPRENDIZAGEM

32. Forneça instruções para desenhar um círculo com centro (100, 100) e raio 25.

33. Forneça instruções para desenhar uma letra “V” usando dois segmentos de linha.

34. Forneça instruções para desenhar uma string com a letra “V”.

35. Quais são os valores das cores RGB de Color.BLUE?

36. Como você desenha um quadrado amarelo contra um fundo vermelho?

A evolução da internet

O Fato Aleatório 2.2 investiga a evolução da internet desde seu humilde começo como uma rede de pesquisa até seu crescimento explosivo que iniciou quando Marc Andreesen, um estudante de pós-graduação, lançou o primeiro navegador Web.

F

ATOALEATÓRIO

2.2

RESUMO DO CAPÍTULO

1. Em Java, cada valor tem um tipo.

2. Você usa variáveis para armazenar valores que deseja utilizar em um momento pos- terior.

3. Identifi cadores para variáveis, métodos e classes são compostos de letras, dígitos e caracteres de sublinhado.

4. Por convenção, os nomes das variáveis devem iniciar com letra minúscula.

5. Utilize o operador de atribuição (=) para alterar o valor de uma variável.

6. Todas as variáveis devem ser inicializadas antes de você acessá-las.

7. Objetos são entidades no seu programa que você manipula chamando métodos.

8. Um método é uma seqüência de instruções que acessam os dados de um objeto.

9. Uma classe defi ne os métodos que você pode aplicar aos objetos dela.

10. A interface pública de uma classe especifi ca o que você pode fazer com objetos dela. A implementação oculta descreve como essas ações são executadas.

11. Um parâmetro é uma entrada para um método.

12. O parâmetro implícito de uma chamada de método é o objeto em que o método é invocado.

13. O valor de retorno de um método é um resultado que o método calculou para uso pelo código que o chamou.

14. Um nome de método é sobrecarregado se uma classe tiver mais de um método com o mesmo nome (mas tipos diferentes de parâmetros).

15. O tipo double indica números de ponto fl utuante que podem ter partes fracionárias.

16. Em Java, números não são objetos e tipos numéricos não são classes.

17. Os números podem ser combinados por operadores aritméticos como +, - e *.

18. Utilize o operador new, seguido por um nome de classe e parâmetros, para construir novos objetos.

19. Um método de acesso não altera o estado do seu parâmetro implícito. Um método modifi cador altera o estado.

20. Determinar o resultado esperado antecipadamente é uma parte importante do proces- so de teste.

21. Classes Java são agrupadas em pacotes. Utilize a instrução import para usar classes defi nidas em outros pacotes.

22. A documentação da API (Application Programming Interface) lista as classes e mé- todos da biblioteca Java.

23. Uma referência a objeto descreve a localização de um objeto.

24. Múltiplas variáveis de objeto podem conter referências ao mesmo objeto.

25. Variáveis numéricas armazenam números. Variáveis de objeto armazenam referências.

26. Para mostrar um frame, construa um objeto JFrame, confi gure seu tamanho e torne-o visível.

27. Para exibir um desenho em um frame, defi na uma classe que estende a classe JComponent.

28. Coloque as instruções de desenho dentro do método paintComponent. Esse método é chamado sempre que o componente precisa ser redesenhado.

29. A classe Graphics permite manipular o estado dos elementos gráfi cos (como a cor atual).

30. A classe Graphics2D possui métodos para desenhar formas.

31. Utilize uma coerção (ou typecasting) para recuperar o objeto Graphics2D a partir do parâmetro Graphics do método paintComponent.

32. Ellipse2D.Double e Line2D.Double são classes que descrevem formas gráfi cas.

33. O método drawString desenha uma string, iniciando no seu ponto de base.

34. Quando você confi gura uma nova cor no contexto gráfi co, ela é utilizada nas opera- ções subseqüentes de desenho.

LEITURA ADICIONAL

1. http://java.sun.com/javase/6/docs/api/index.html A documentação da API Java.

CLASSES, OBJETOS E MÉTODOS INTRODUZIDOS NESTE CAPÍTULO

java.awt.Color java.awt.Component getHeight getWidth setSize setVisible java.awt.Frame setTitle java.awt.geom.Ellipse2D.Double java.awt.geom.Line2D.Double java.awt.geom.Point2D.Double java.awt.Graphics setColor java.awt.Graphics2D draw drawString fi ll java.awt.Rectangle translate getX getY getHeight getWidth java.lang.String length replace toLowerCase toUpperCase javax.swing.JComponent paintComponent javax.swing.JFrame setDefaultCloseOperation

EXERCÍCIOS DE REVISÃO

Exercício R2.1. Explique a diferença entre um objeto e uma referência a objeto.

Exercício R2.2. Explique a diferença entre um objeto e uma variável de objeto.

Exercício R2.4. Forneça o código Java para construir um objeto da classe Rectangle e para declarar uma variável de objeto da classe Rectangle.

Exercício R2.5. Explique a diferença entre o símbolo = em Java e na matemática.

Exercício R2.6. Variáveis não-inicializadas podem ser um problema sério. Você sempre deve inicializar cada variável int ou double com zero? Explique as vantagens e as des- vantagens dessa estratégia.

Exercício R2.7. Forneça o código Java para construir os seguintes objetos:

a. Um retângulo com centro (100, 100) e todos os comprimentos de lado iguais a 50.

b. Uma string "Hello, Dave!". Crie objetos, não variáveis de objeto.

Exercício R2.8. Repita o Exercício R2.7, mas desta vez defi na as variáveis de objeto que são inicializadas com os objetos requeridos.

Exercício R2.9. Encontre os erros nestas instruções:

a. Rectangle r = (5, 10, 15, 20);

b. double width = Rectangle(5, 10, 15, 20).getWidth();

c. Rectangle r;

r.translate(15, 25);

d. r = new Rectangle();

r.translate("far, far away!");

Exercício R2.10. Identifi que dois métodos de acesso e dois métodos modifi cadores da classe Rectangle.

Exercício R2.11. Examine a documentação da API da classe Rectangle e localize o método. void add(int newx, int newy)

Analise a documentação do método. Depois, determine o resultado das instruções a seguir: Rectangle box = new Rectangle(5, 10, 20, 30);

box.add(0, 0);

Se você não estiver seguro, escreva um pequeno programa de teste ou use o BlueJ.

Exercício R2.12. Encontre um método sobrecarregado da classe String.

Exercício R2.13. Localize um método sobrecarregado da classe Rectangle.

Exercício R2.14. Qual é a diferença entre uma aplicação de console e uma aplicação grá- fi ca?

Exercício R2.15. Quem chama o método paintComponent de um componente? Quando ocorre a chamada ao método paintComponent?

Exercício R2.16. Por que o parâmetro do método paintComponent tem um tipo Graphics e não um Graphics2D?

Exercício R2.18. Por que são utilizadas uma classe de visualizadores e uma classe de componentes separadas para programas gráfi cos?

Exercício R2.19. Como você especifi ca uma cor de texto?

Exercícios de revisão adicionais estão disponíveis no WileyPLUS (recurso da editora original).

EXERCÍCIOS DE PROGRAMAÇÃO

Exercício P2.1. Escreva um programa AreaTester que constrói um objeto Rectangle e então calcula e imprime sua área. Utilize os métodos getWidth e getHeight. Imprima a resposta esperada.

Exercício P2.2. Escreva um programa PerimeterTester que constrói um objeto Rectangle e então calcula e imprime seu perímetro. Utilize os métodos getWidth e getHeight. Impri- ma a resposta esperada.

Exercício P2.3. Escreva um programa chamado FourRectanglePrinter que constrói um objeto Rectangle, imprime sua localização chamando System.out.println(box) e então o traduz e imprime mais três vezes, de modo que, se os retângulos fossem desenhados, eles formariam um grande retângulo:

Exercício P2.4. O método intersection calcula a intersecção de dois retângulos – isto é, o retângulo formado por dois retângulos que se sobrepõem:

Você chama esse método como a seguir: Rectangle r3 = r1.intersection(r2);

Escreva um programa IntersectionPrinter que constrói dois objetos retângulo, os im- prime e então imprime o objeto retângulo que descreve a interseção. Depois, o programa deve imprimir o resultado do método intersection quando os retângulos não se sobrepu- serem. Adicione um comentário ao seu programa que explica como é possível dizer se o retângulo resultante está vazio.

Exercício P2.5. Na biblioteca Java, uma cor é especifi cada pelos seus componentes de ver- melho, verde e azul com valores entre 0 e 255. Escreva um programa BrighterDemo que constrói um objeto Color com valores de vermelho, verde e azul de 50, 100 e 150. Aplique então o método brighter e imprima os valores de vermelho, verde e azul da cor resultan- te. (Você não verá realmente a cor – consulte a Seção 2.13 sobre como exibir cores.)

Exercício P2.6. Repita o Exercício P2.5, mas aplique o método darker duas vezes ao ob- jeto predefi nido Color.RED. Chame sua classe DarkerDemo.

Exercício P2.7. A classe Random implementa um gerador de números aleatórios, que pro- duz seqüências de números que parecem ser aleatórios. Para gerar inteiros aleatórios, você constrói um objeto da classe Random e então aplica o método nextInt. Por exemplo, a chamada generator.nextInt(6) fornece um número aleatório entre 0 e 5.

Escreva um programa DieSimulator que usa a classe Random para simular o lançamento de um dado, imprimindo um número aleatório entre 1 e 6 toda vez que o programa é executado.

Exercício P2.8. Escreva um programa LotteryPrinter que seleciona uma combinação em uma loteria. Nessa loteria, os apostadores podem escolher 6 números (possivelmente re- petidos) entre 1 e 49. (Em uma loteria real, repetições não são permitidas, mas ainda não discutimos as construções de programação que seriam necessárias para lidar com esse problema.) Seu programa deve imprimir uma frase como “Jogue essa combinação – ela o tornará rico!”, seguida por uma combinação de números.

Exercício P2.9. Escreva um programa ReplaceTester que codifi ca uma string substituindo todas as letras "i" por "!" e todas as letras "s" por "$". Utilize o método replace. De- monstre que você pode codifi car corretamente a string "Mississippi". Imprima o resul- tado real e o esperado.

Exercício P2.10. Escreva um programa HollePrinter que muda as letras "e" e "o" em uma string. Utilize o método replace repetidamente. Demonstre que a string "Hello, World!" transforma-se em "Holle, Werld!".

Exercício P2.11. Escreva um programa gráfi co que desenhe seu nome em vermelho, contido dentro de um retângulo azul. Forneça uma classe NameViewer e uma classe NameComponent.

Exercício P2.12. Escreva um programa gráfi co que desenhe 12 strings, uma para cada uma das 12 cores padrão, além de Color.WHITE, e cada uma em sua própria cor. Forneça uma classe ColorNameViewer e uma classe ColorNameComponent.

Exercício P2.13. Escreva um programa que desenha dois quadrados sólidos: um em cor- de-rosa e um em roxo. Utilize uma cor padrão para um deles e uma cor personalizada para o outro. Forneça uma classe TwoSquareViewer e uma classe TwoSquareComponent.

Exercício P2.14. Escreva um programa que preencha a janela com uma grande elipse, com um contorno preto e preenchida com sua cor favorita. A elipse deverá tocar os limi- tes da janela, mesmo se a janela for redimensionada.

Exercício P2.15. Escreva um programa para plotar o rosto a seguir.

Forneça uma classe FaceViewer e uma classe FaceComponent.

Exercícios de programação adicionais estão disponíveis no WileyPLUS (recurso da edi- tora original).

PROJETOS DE PROGRAMAÇÃO

Projeto 2.1. A classe GregorianCalendar descreve um ponto no tempo, como medido

pelo calendário gregoriano, o calendário padrão comumente utilizado em quase todo o mundo atual. Você constrói um objeto GregorianCalendar a partir de um ano, mês e dia, como no exemplo a seguir:

GregorianCalendar cal = new GregorianCalendar(); // Data atual GregorianCalendar eckertsBirthday = new GregorianCalendar(1919, Calendar.APRIL, 9);

Utilize as constantes Calendar.JANUARY . . . Calendar.DECEMBER para especifi car o mês. O método add pode ser utilizado para adicionar alguns dias a um objeto GregorianCalendar:

cal.add(Calendar.DAY_OF_MONTH, 10); // Agora cal é dez dias depois de hoje Esse é um método modifi cador – ele altera o objeto cal.

O método get pode ser utilizado para consultar um objeto GregorianCalendar: int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);

int month = cal.get(Calendar.MONTH); int year = cal.get(Calendar.YEAR);

int weekday = cal.get(Calendar.DAY_OF_WEEK); // 1 é domingo, 2 é segunda-feira,. . . , 7 é sábado

Sua tarefa é escrever um programa que imprime estas informações: A data e o dia da semana daqui a 100 dias a partir da data atual

O dia da semana do seu aniversário

A data daqui a 10.000 dias a partir do seu aniversário

Utilize o aniversário de um cientista da computação se você não quiser revelar seu pró- prio aniversário.

Projeto 2.2. Execute o programa a seguir:

import java.awt.Color; import javax.swing.JFrame; import javax.swing.JTextField; public class FrameTester {

public static void main(String[] args) {

JFrame frame = new JFrame(); frame.setSize(200, 200);

JTextField text = new JTextField("Hello, World!"); text.setBackground(Color.PINK); frame.add(text); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }

Modifi que o programa desta maneira: Dobre o tamanho do frame

Mude a saudação para “Hello,

seu nome!”

Mude a cor de fundo para verde pálido (veja o Exercício P2.5)

RESPOSTAS ÀS PERGUNTAS DE AUTOVERIFICAÇÃO DA APRENDIZAGEM

1. int e String

2. Somente os dois primeiros são identifi cadores válidos.

3. String myName = "John Q. Public";

4. Não, o lado esquerdo do operador = deve ser uma variável.

5. greeting = "Hello, Nina!"; Observe que:

String greeting = "Hello, Nina!";

não é a resposta correta – essa instrução defi ne uma nova variável.

6. river.length() ou "Mississippi".length()

7. System.out.println(greeting.toUpperCase());

8. Não é válido. A variável river é do tipo String. O método println não é um método da classe String.

9. O parâmetro implícito é river. Não há parâmetro explícito. O valor de retorno é 11.

10. "Missississi"

11. 12

12. Como public String toUpperCase(), sem parâmetro explícito e sem tipo de retorno String.

13. double

15. (x + y) * 0.5

16. new Rectangle(90, 90, 20, 20)

17. 0

18. Um método de acesso – não modifi ca a string original, mas retorna uma nova string em letras maiúsculas.

19. box.translate(-5, -10), desde que o método seja chamado logo depois de armaze- nar o novo retângulo em box.

20. x: 30, y: 25

21. Porque o método translate não modifi ca a forma do retângulo.

22. Adicione a instrução import java.util.Random; na parte superior de seu programa.

23. toLowerCase

24. "Hello, Space !" – somente os espaços iniciais e fi nais são cortados.

25. Agora greeting e greeting2 referenciam o mesmo objeto String.

26. As duas variáveis ainda referem-se à mesma string e a string não foi modifi cada. Lembre-se de que o método toUpperCase constrói uma nova string que contém carac- teres em letras maiúsculas, deixando a string original inalterada.

27. Modifi que o programa EmptyFrameViewer como mostrado a seguir: frame.setSize(300, 300);

frame.setTitle("Hello, World!");

28. Construa dois objetos JFrame, confi gure cada um dos seus tamanhos e chame setVisible(true) em cada um deles.

29. Rectangle box = new Rectangle(5, 10, 20, 20);

30. Substitua a chamada a box.translate(15, 25) por box = new Rectangle(20, 35, 20, 20);

31. O compilador reclama que g não tem um método draw.

32. g2.draw(new Ellipse2D.Double(75, 75, 50, 50));

33. Line2D.Double segment1 = new Line2D.Double(0, 0, 10, 30); g2.draw(segment1);

Line2D.Double segment2 = new Line2D.Double(10, 30, 20, 0); g2.draw(segment2);

34. g2.drawString("V", 0, 30);

35. 0, 0, 255

36. Primeiro preencha um grande quadrado vermelho e então preencha um pequeno qua- drado amarelo dentro:

g2.setColor(Color.RED);

g2.fi ll(new Rectangle(0, 0, 200, 200)); g2.setColor(Color.YELLOW);

3