Instanciar um objeto e atribuir um objeto a uma classe com operador =

8 respostas
D

Oi pessoal, sou iniciante em JAVA e estou estudando pelo livro JAVA Como Programar 3th Edição da DEITEL.

Estou no capítulo 11 e fiquei com uma grande dúvida que espero possa ser esclarecida pelos gurus deste fórum :smiley: !

Aqui esta o código da página 517 a 518 do exemplo Shapes.java:

// Fig. 11.22: Shapes.java
// Demonstrating some Java2D shapes

package examples;

import javax.swing.<em>;

import java.awt.event.</em>;

import java.awt.<em>;

import java.awt.geom.</em>;

import java.awt.image.*;
public class Shapes extends JFrame {

public Shapes()

{

super( Drawing 2D shapes );
setSize( 425, 160 );
  show();

}

public void paint( Graphics g )

{

// create 2D by casting g to Graphics2D

Graphics2D g2d = ( Graphics2D ) g;
// draw 2D ellipse filled with a blue-yellow gradient
  g2d.setPaint(
     new GradientPaint( 5, 30,         // x1, y1
                        Color.blue,    // initial Color
                        35, 100,       // x2, y2
                        Color.yellow,  // end Color
                        true ) );      // cyclic
  g2d.fill( new Ellipse2D.Double( 5, 30, 65, 100 ) );

  // draw 2D rectangle in red
  g2d.setPaint( Color.red );                  
  g2d.setStroke( new BasicStroke( 10.0f ) ); 
  g2d.draw(
     new Rectangle2D.Double( 80, 30, 65, 100 ) );

  // draw 2D rounded rectangle with a buffered background
  BufferedImage buffImage =
     new BufferedImage(
        10, 10, BufferedImage.TYPE_INT_RGB );

  Graphics2D gg = buffImage.createGraphics();   
  gg.setColor( Color.yellow ); // draw in yellow
  gg.fillRect( 0, 0, 10, 10 ); // draw a filled rectangle
  gg.setColor( Color.black );  // draw in black
  gg.drawRect( 1, 1, 6, 6 );   // draw a rectangle
  gg.setColor( Color.blue );   // draw in blue
  gg.fillRect( 1, 1, 3, 3 );   // draw a filled rectangle
  gg.setColor( Color.red );    // draw in red
  gg.fillRect( 4, 4, 3, 3 );   // draw a filled rectangle

  // paint buffImage onto the JFrame
  g2d.setPaint(
     new TexturePaint(
        buffImage, new Rectangle( 10, 10 ) ) );
  g2d.fill(
     new RoundRectangle2D.Double(
        155, 30, 75, 100, 50, 50 ) );

  // draw 2D pie-shaped arc in white
  g2d.setPaint( Color.white );
  g2d.setStroke( new BasicStroke( 6.0f ) ); 
  g2d.draw(
     new Arc2D.Double(
        240, 30, 75, 100, 0, 270, Arc2D.PIE ) );

  // draw 2D lines in green and yellow
  g2d.setPaint( Color.green );
  g2d.draw( new Line2D.Double( 395, 30, 320, 150 ) );

  float dashes[] = { 10 };

  g2d.setPaint( Color.yellow );    
  g2d.setStroke(
     new BasicStroke( 4,                      
                      BasicStroke.CAP_ROUND,  
                      BasicStroke.JOIN_ROUND, 
                      10, dashes, 0 ) );      
  g2d.draw( new Line2D.Double( 320, 30, 395, 150 ) );

}

public static void main( String args[] )

{

Shapes app = new Shapes();
app.addWindowListener(
     new WindowAdapter() {
        public void windowClosing( WindowEvent e )
        {
           System.exit( 0 );
        }
     }
  );

}
}

Minha dúvida é a seguinte: na construção da imagem do retângulo arredondado 2D com fundo armazenado em buffe, primeiro é instanciado um objeto buffImage para criar um buffer padrão de preenchimento, correto?
O que eu não entendi é porque e como eu sei que eu irei precisar do comando Graphics2D gg = buffImage.createGraphics(); ?
O livro diz que esta linha cria um objeto Graphic2D que pode ser utilizado para desenhar na classe BufferedImage.
Porque aqui é utilizado uma atribuição de um método que retorna um objeto Graphics2D para um Graphics2D gg, sendo que no comando g2d.setPaint( new TexturePaint( buffImage, new Rectangle( 10, 10 ) ) ); não há mais referência a gg e sim a buffImage como argumento.
Então o comando Graphics2D gg = buffImage.createGraphics(); cria uma referência gg ao objeto buffImage? Se sim, porque não utilizar o buffImage diretamente para setColor, fillRect, etc (para criar a textura) e porque?

Obrigado pela atenção de todos,

Druid®

8 Respostas

A

Quando você faz isso,

você está dizendo que o retorno do método createGraphics() da classe buffImage é do tipo Graphics2D e vai ser chamado por gg.
Não é obrigatório que você fizesse isso, mais toda vez que precisasse usar esse tipo de objeto, teria que escrever buffImage.createGraphics(); e não simplismente gg. Entendeu?

D

Ok meu amigo ateubh, até ai eu entendi.

Bom, então me diz se eu estou certo, na realidade o comando:

Graphics2D gg = buffImage.createGraphics();

Não esta instanciando o objeto gg e sim criando uma referencia a classe Graphics2D, que por sua vez, acredito deva ser uma superclasse e então essa atribuição é um polimorfismo, correto?

Obrigado por me responder.

Atenciosamente,

Druid®

A

Me desculpe, mas você está incorreto… vou tentar explicar melhor.

buffImage é um objeto que possui um método (createGraphics()) que retorna um objeto do tipo Graphics2D;

quando faço Graphics2D gg eu crio um objeto do tipo Graphics2D e chamo ele de gg.

seu eu não fizesse assim Graphics2D gg = buffImage.createGraphics(), toda vez que eu quisesse usar um objeto do tipo Graphics2D, teria de fazer essa chamada buffImage.createGraphics(), o que pode deixar o seu código confuso, pois nem sempre o nome do método exemplifica o seu retorno, além de aumentar o seu código.

se você fizesse assim Graphics2D criaGrafico = buffImage.createGraphics() toda vez que quisesse usar o objeto createGraphics, seria só chamar o criaGrafico, o que poderia deixar o código mais claro ao se dar manutenção. Entendeu?

D

Oi amigo ateubh, OK!

Só uma coisa ainda não ficou clara para mim, voce me disse que o comando Graphics2D gg = buffImage.createGraphics(), cria um objeto Graphics2D gg (isto é uma instanciação implícita certo?) (não estou me confundindo sobre o nome gg ou criaGrafico), minha dúvida é este: se o comando acima ao criar o objeto Graphics2D gg, ele faz referência ao objeto BufferedImage buffImage (???), porque no comando abaixo, não existe referência ao objeto gg e sim ao objeto buffImage, é essa a minha dúvida, do mecanismo de atribuição que eu ainda não compreendi, pois fiz uma analogia com o polimorfismo o que voce me disse estar errada???

// paint buffImage onto the JFrame

g2d.setPaint(

new TexturePaint(

buffImage, new Rectangle( 10, 10 ) ) );

g2d.fill(

new RoundRectangle2D.Double(

155, 30, 75, 100, 50, 50 ) );

Abraços,

Druid®

A

Um exemplo de poliformismo, é quando você tem vários métodos com assinaturas diferentes e quando chama um o complidador sabe em tempo de execução qual método ele deve executar.

Vou te explicar esse pedaço do código:

public void paint( Graphics g ) 
{ 
// create 2D by casting g to Graphics2D 
Graphics2D g2d = ( Graphics2D ) g; 

// draw 2D ellipse filled with a blue-yellow gradient 
g2d.setPaint( 
new GradientPaint( 5, 30, // x1, y1 
Color.blue, // initial Color 
35, 100, // x2, y2 
Color.yellow, // end Color 
true ) ); // cyclic 
g2d.fill( new Ellipse2D.Double( 5, 30, 65, 100 ) );

Quando você olha a assinatura do método dele public void paint( Graphics g ) você percebe que ele recebe um objeto do tipo Graphics e o chama de g.

Nessa linha Graphics2D g2d = ( Graphics2D ) g; ele pega o objeto Graphics e por casting o transforma em Graphics2D, mas isso se deve a herança e não polifomismo, já que a classe Graphics2D herda a classe Graphics.

OK?

D

OK meu amigo ateubh!

Mas voce ainda não respondeu a minha dúvida principal: como o java sabe que todos aqueles métodos aplicados ao objeto gg vão refletir diretamente em (objeto buffimage):

// paint buffImage onto the JFrame

g2d.setPaint(

new TexturePaint(

buffImage, new Rectangle( 10, 10 ) ) );

g2d.fill(

new RoundRectangle2D.Double(

155, 30, 75, 100, 50, 50 ) );

já que o primeiro argumento recebido por TexturePaint é o objeto “buffImage” (e todas as operações para produzir a textura foram executadas pelos métodos no objeto “gg”), é isso que eu não compreendi ainda, este mecanismo que não consegui entender?

Voce pode me explicar por favor, detalhadamente o que faz esta linha de atribuição ( Graphics2D gg = buffImage.createGraphics(); ), por favor seja didático, pormenorize pois ainda estou começando em java e sinto que esta explicação vai ser muito importante não só pra mim, mas para todos que estão inciando em programação orientada a objeto.

Não posso continuar a estudar JAVA com esta dúvida meu amigo, sério!

Por favor me ajudem ai pessoal, isso ainda está muito nebuloso no meu entendimento.

Abraços,

Druid®

D

Up!

L

Graphics2D gg = buffImage.createGraphics();
o “gg” é um handle que guarda no endereço de memória o objeto “buffImage”
nesta mesma linha o buffImage evoca o método createGraphics, onde é carregado os
parâmetros no handle:

gg.setColor( Color.yellow ); // draw in yellow
gg.fillRect( 0, 0, 10, 10 ); // draw a filled rectangle
gg.setColor( Color.black ); // draw in black
gg.drawRect( 1, 1, 6, 6 ); // draw a rectangle
gg.setColor( Color.blue ); // draw in blue
gg.fillRect( 1, 1, 3, 3 ); // draw a filled rectangle
gg.setColor( Color.red ); // draw in red
gg.fillRect( 4, 4, 3, 3 ); // draw a filled rectangle

então na linha seguinte ele chama :

// paint buffImage onto the JFrame

g2d.setPaint(

new TexturePaint(

buffImage, new Rectangle( 10, 10 ) ) );

g2d.fill(

new RoundRectangle2D.Double(

155, 30, 75, 100, 50, 50 ) );

buffImage que ele chamou está guardada no endereço de memória que o handle gg apontou,
e lá seus métodos criaram os gráficos que foram chamados através do gg
Ex. gg.filRect…

Espero ter explicado.

Criado 30 de maio de 2006
Ultima resposta 21 de set. de 2007
Respostas 8
Participantes 3