Dificuldade Graphics2D

15 respostas
M

Pessoal, estou desenvolvendo uma interface onde o usuario escolhe uma forma geométrica(triangulo, circulo, retangulo), entra com os valores(tamanho e localizacao), clica no botao Desenhar e essa interface deve desenhar essas imagens na tela.
Logo apos o usuario pode selecionar uma das transformacoes (rotate, scale, shear, translate),entrar com os valores, e clicar no botao Transformar e o programa deve transformar a imagem de acordo com os parametros.

Problemas encontrados:
1- a imagem é gerada na tela em qualquer posição: preciso delimitar um espaço onde será desenhado a imagem. Como devo proceder?
2- Quando o usuario desenha uma imagem e logo em seguida muda os parametros e clica em desenhar novamente, o programa desenha outra imagem sem apagar a primeira. Como faço para apagar a imagem gerada?
3-O botão Transformar não funciona. Nao faz nenhuma transformacao.
4- Quais são as formas corretas de se usar o repaint() e update()?

Por favor, deem uma luz!!! já tem 15 dias que estou quebrando a cabeça com isso e não consigo resolver. Os tutoriais e apostilas da net são muito superficiais nesse assunto.

Resumidamente esse é meu codigo

public class Principal extends javax.swing.JFrame {

    public Graphics2D d;

}

public void paint (Graphics2D d){
        d.setColor (Color.BLUE);

//desenha retangulo
        if(retangulo.isSelected()){
            posicaox= Integer.parseInt(posx.getText());
            posicaoy= Integer.parseInt(posy.getText());
            comprimento= Integer.parseInt(comp.getText());
            largura= Integer.parseInt(larg.getText());
            d.drawRect(posicaox, posicaoy ,comprimento , largura);

      }

//desenha circulo
        if(circun.isSelected()){
             posicaox= Integer.parseInt(posx1.getText());
            posicaoy= Integer.parseInt(posx1.getText());
            comprimento= Integer.parseInt(comp1.getText());
            largura= Integer.parseInt(larg1.getText());
            d.drawOval(posicaox, posicaoy ,comprimento , largura);

        }

//desenha triangulo
        if(triang.isSelected()){
            p1x= Integer.parseInt(x1.getText());
            p1y= Integer.parseInt(y1.getText());
            p2x= Integer.parseInt(x2.getText());
            p2y= Integer.parseInt(y2.getText());
            p3x= Integer.parseInt(x3.getText());
            p3y= Integer.parseInt(y3.getText());
            d.drawLine(p1x, p1y, p2x, p2y);
            d.drawLine(p2x, p2y, p3x, p3y);
            d.drawLine(p3x, p3y, p1x, p1y);

        }
//Transformar translateDouble
        if(transd.isSelected()){
            translatex= Double.parseDouble(tx.getText());
            translatey= Double.parseDouble(ty.getText());
            d.translate(translatex, translatey);
        }

//Transformar translateInt
        if(transi.isSelected()){
            posicaox= Integer.parseInt(tix.getText());
            posicaoy= Integer.parseInt(tiy.getText());
            d.translate(posicaox, posicaoy);
        }
//Transformar rotateDoble        

if (rotate.isSelected()){

            angulo= Double.parseDouble(ang.getText());
            d.rotate(angulo);
         }
//Transformar RotateTranslate  
        if (rotatem.isSelected()){
            angulo= Double.parseDouble(rmang.getText());
            translatex= Double.parseDouble(rmx.getText());
            translatey= Double.parseDouble(rmy.getText());
            d.rotate(angulo, translatex, translatey);
           
        }
//Transformar Scale  
        if(scale.isSelected()){
            fatorx= Double.parseDouble(fx.getText());
            fatory= Double.parseDouble(fy.getText());
            d.scale(fatorx, fatory);
           }
//Transformar Shear  
        if(shear.isSelected()){
            fatorx= Double.parseDouble(sx.getText());
            fatory= Double.parseDouble(sy.getText());
            d.shear(fatorx, fatory);
             }
    }
//acao do botão Desenhar
private void desenhActionPerformed(java.awt.event.ActionEvent evt) {                                       
     repaint();
    }    

//acao do botão Transformar
   private void transformarActionPerformed(java.awt.event.ActionEvent evt) {                                            
        
        repaint();
    }

15 Respostas

Marky.Vasconcelos

Para apagar a de traz

public void paint (Graphics2D d){  
         super.paint(d);

Mas acho melhor voce implementar essa lógica em um JPanel sobreescrevendo o método paintComponent(Graphics).

E o seu botão não esta sendo chamado por que o java chama o método paint(Graphics) e não paint(Graphics2D)

ViniGodoy

Sabe porque ele não apaga a imagem?

A explicação está em praticamente todas as documentações do Swing. Ao invés de achar como um método funciona, e estranhar dele não atender as suas suposições, que tal ler um pouco? Ajuda muito saber o que você está fazendo, ao invés de recorrer a tentativa e erro. Um único dia de leitura poderia ter te poupado de todos os 15 dias de estresses.

Existem dezenas de erros no seu código:

  1. Você não deve armazenar o objeto Graphics2D como um atributo. Ele tende a se perder entre um repaint e outro;
  2. Você não deve usar o Graphics2D diretamente. Faça uma cópia dele no início do método com o createGraphics(), e libere essa cópia ao final com o Dispose().
  3. Siga a dica do Mark e faça um filho de JPanel, sobrescrevendo então o método paintComponent.
  4. Você deve aplicar as transformações antes de desenhar a forma, não depois. As transformações não manipulam a imagem já desenhada. O que elas fazem é alterar o seu espaço coordenado, para que novos desenhos saiam modificados. Leia os seguintes artigos para entender esse conceito melhor (eles falam de transformação no OpenGL, mas o conceito básico é o mesmo):
    http://vinigodoy.wordpress.com/2008/02/10/sistemas-de-coordenadas/
    http://vinigodoy.wordpress.com/2008/02/17/transformacoes/
    http://vinigodoy.wordpress.com/2008/02/26/aplicando-as-transformacoes/

Aqui você encontra ótimas documentações sobre o assunto:
http://java.sun.com/docs/books/tutorial/2d/TOC.html
http://java.sun.com/products/jfc/tsc/articles/painting/
http://fivedots.coe.psu.ac.th/~ad/jg/
http://www.cokeandcode.com/node/6

M

pessoal,

obrigado pela atenção e pelas dicas. Já li os materiais e um livro so Computação grafica. Acontece que eu sou iniciante em java e ainda não tenho muito as manhas de OO.

Como eu usaria esse createGraphics()? dentro do paint?
Como faço para sobrescrever o paintComponent?
Então pra aplicar as transformaçoes eu teria que redesenhar as imagens e ao mesmo temo chamar a transformaçao?
apliquei o super.paint(d); dentro do paint e não funcionou, não apagou a imagem anterior.

M

Segue anexo meu código completo. Se possível indiquem onde estou errando. Quero aprender Java e preciso da ajuda de vcs.

ViniGodoy

marcosoc:
Como eu usaria esse createGraphics()? dentro do paint?
Como faço para sobrescrever o paintComponent?
Então pra aplicar as transformaçoes eu teria que redesenhar as imagens e ao mesmo temo chamar a transformaçao?
apliquei o super.paint(d); dentro do paint e não funcionou, não apagou a imagem anterior.

Todas as repostas dessas perguntas estão nos links acima.

public void paintComponent(Graphics2D g) { Graphics2D g2d = (Graphics2D) g.createGraphics(); //Seus desenhos aqui g2d.dispose(); }

Você deve aplicar a transformações antes de desenhar. Por antes, entenda “antes de dar o draw”. Leia os tópicos que coloquei para você ali em cima para entender exatamente o que são transformações.

Se você quer mesmo aprender java, estude os links que te passei. Se eu te passar o código pronto, você só vai resolver seu problema, não aprender Java…

M

Ok, já estou estudando.

Uma duvida:

Eu crio o atributo d dentro do metodo paint, só que eu preciso usá-lo fora desse método. Tem como? Como vc viu, eu estou usando varios if’s dentro do paint, mas eu queria poder chamar os metodos para desenhar e transformar os objetos de outras funcoes fora do paint. Quando eu chamar o repaint() ele fará as devidas modificaçoes em d??? como devo proceder???

public void paint (Graphics g){

Graphics2D d = (Graphics2D) g;

}
M

Onde acho algo mais claro sobre Transforming Shapes e AffineTransform ?

Nessa pg da sun tá muito dificil entender.

http://java.sun.com/docs/books/tutorial/2d/advanced/transforming.html

T

marcosoc:
Ok, já estou estudando.

Uma duvida:

Eu crio o atributo d dentro do metodo paint, só que eu preciso usá-lo fora desse método. Tem como? Como vc viu, eu estou usando varios if’s dentro do paint, mas eu queria poder chamar os metodos para desenhar e transformar os objetos de outras funcoes fora do paint. Quando eu chamar o repaint() ele fará as devidas modificaçoes em d??? como devo proceder???

public void paint (Graphics g){

Graphics2D d = (Graphics2D) g;

}</blockquote>

Ora, é só passá-lo como parâmetro para outro método.

ViniGodoy

Você tem idéia do que a transformação está transformando?
Antes de entender como a classe da Sun funciona, é necessário entender o que é uma transformação.

Você leu os artigos sobre esse assunto que eu postei ali em cima? Os três que vem do meu blog?
É muito difícil entender o funcionamento de uma classe, se você não tiver a menor noção do conceito que ela implementa.

M

Olha, já li tudo o que vc me passou e outras coisas mais. Não estou conseguindo. O programa apenas desenha a imagem mas não transforma. E tb não sei como fazer para delimitara area onde o desenho deve aparecer.

Preciso de uma ajuda mais objetiva. Perdi mais um dia com esse programinha e nada. Nao sei mais o que fazer.

Obrigado pela atencao

package CG;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.AffineTransform;

public class Principal extends javax.swing.JFrame {
//MinhaTela tela;
int posicaox =10;
int posicaoy =10;
int comprimento =220;
int largura =220;
double angulo =0;
int p1x=0,p2x=0,p3x=0,p1y=0,p2y=0,p3y=0;


  double translatex = 0.0;

  double translatey = 0.0;

  double rotateangulo = 0.0;

  double rotateX = 150.0;

  double rotateY = 150.0;

  double fatorx = 1.0;

  double fatory = 1.0;

  float width = 1.0f;
  private final int LARG_DES = 600;
  private final int ALT_DES = 500;

  AffineTransform at = new AffineTransform();

    public Principal() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        initComponents();
    }

//verifica e desenha a opcao que o usuario escolheu
public void paint(Graphics g) {
        //super.paint(g);
        System.out.println("paint");
		Graphics2D d = (Graphics2D) g;
        d.setColor (Color.BLUE);

        if(retangulo.isSelected()){
            posicaox= Integer.parseInt(posx.getText());
            posicaoy= Integer.parseInt(posy.getText());
            comprimento= Integer.parseInt(comp.getText());
            largura= Integer.parseInt(larg.getText());
            d.drawRect(posicaox, posicaoy ,comprimento , largura);
      }
        if(circun.isSelected()){

            posicaox= Integer.parseInt(posx1.getText());
            posicaoy= Integer.parseInt(posx1.getText());
            comprimento= Integer.parseInt(comp1.getText());
            largura= Integer.parseInt(larg1.getText());
            d.drawOval(posicaox, posicaoy ,comprimento , largura);

        }
        if(triang.isSelected()){

            p1x= Integer.parseInt(x1.getText());
            p1y= Integer.parseInt(y1.getText());
            p2x= Integer.parseInt(x2.getText());
            p2y= Integer.parseInt(y2.getText());
            p3x= Integer.parseInt(x3.getText());
            p3y= Integer.parseInt(y3.getText());
            d.drawLine(p1x, p1y, p2x, p2y);
            d.drawLine(p2x, p2y, p3x, p3y);
            d.drawLine(p3x, p3y, p1x, p1y);

        }

    }
//verifica e apica a transformacao que o usuario escolheu
     public void transform (Graphics2D d){

       if(transd.isSelected()){

            translatex= Double.parseDouble(tx.getText());
            translatey= Double.parseDouble(ty.getText());
            //d.translate(translatex, translatey);
            at.translate(translatex, translatey);

            //update(d);
        }
        if(transi.isSelected()){
            posicaox= Integer.parseInt(tix.getText());
            posicaoy= Integer.parseInt(tiy.getText());
            //d.translate(posicaox, posicaoy);
            at.translate(posicaox, posicaoy);
            //update(d);
        }
         if (rotate.isSelected()){
            angulo= Double.parseDouble(ang.getText());
            d.rotate(angulo);
            posicaox= Integer.parseInt(posx.getText());
            posicaoy= Integer.parseInt(posy.getText());
            comprimento= Integer.parseInt(comp.getText());
            largura= Integer.parseInt(larg.getText());
            d.drawRect(posicaox, posicaoy ,comprimento , largura);
        }
        if (rotatem.isSelected()){
            angulo= Double.parseDouble(rmang.getText());
            translatex= Double.parseDouble(rmx.getText());
            translatey= Double.parseDouble(rmy.getText());
            //d.rotate(angulo, translatex, translatey);
            at.rotate(angulo, translatex, translatey);
           //update(d);
        }
        if(scale.isSelected()){

            fatorx= Double.parseDouble(fx.getText());
            fatory= Double.parseDouble(fy.getText());
            //d.scale(fatorx, fatory);
            at.scale(fatorx, fatory);
            //update(d);
        }
        if(shear.isSelected()){

            fatorx= Double.parseDouble(sx.getText());
            fatory= Double.parseDouble(sy.getText());
            d.shear(fatorx, fatory);
        }
     }
//botao desenhar
    private void desenhActionPerformed(java.awt.event.ActionEvent evt) {                                       
     repaint();
       
    }                                     
//botao transformar
    private void transformarActionPerformed(java.awt.event.ActionEvent evt) {                                            
        System.out.println("transf");
        repaint();
    }                                           
  }
ViniGodoy

Então, pq vc ainda está tentando aplicar as tranformações depois de desenhar? Como eu já falei no outro tópico, você precisa aplica-las antes do desenho, não depois.

Funciona assim, vamos supor que você queira desenhar uma figura rotacionada, e deslocada 10cm para a esquerda.

  1. Você translada o sistema de coordenadas 10cm para esquerda. Ou seja, sua posição 0,0 agora estará na posição 10,0.
  2. Você rotaciona esse sistema de coordenadas na quantidade de graus que quiser;
  3. Você então desenha a figura na tela, na posição 0,0, desse seu novo sistema de coordenadas.

Percebeu a diferença? As transformações atuam sobre o eixo coordenado, não sobre o que está desenhado. Tudo que for desenhado no novo eixo será modificado, não o que já estava desenhado lá.

M

ok, eu já havia entendiado isto, e já testei tb, mas não funcionou. Veja o codigo. Quando eu clico em Transformar ele desenha o retangulo na mesma posicao do não rotacionar.

if (rotate.isSelected()){ System.out.println("rotate"); angulo= Double.parseDouble(ang.getText()); d.rotate(angulo); // at.rotate(angulo); posicaox= Integer.parseInt(posx.getText()); posicaoy= Integer.parseInt(posy.getText()); comprimento= Integer.parseInt(comp.getText()); largura= Integer.parseInt(larg.getText()); d.drawRect(posicaox, posicaoy ,comprimento , largura); }

ViniGodoy

Bem, estude o código e adapte-o as suas necessidades. Coloquei uns comentários para que você entenda o que foi feito.

Até baixei seu código, mas estava tão bagunçado que achei melhor refazer do zero.

M

Vini, parabens e muito obrigado. Vc fez isso tudo hoje?

Uma dúvida: tem como fazer o objeto mudar de posicao depois que ele foi desenhado? ou seja, apagar o objeto e cria-lo em outro lugar aplicando uma transformação???

ViniGodoy

Fiz sim, tirei um tempinho depois do almoço…

Sim, basta alterar as propriedades dos objetos que estão na lista, dentro do painel.

Criado 18 de março de 2009
Ultima resposta 20 de mar. de 2009
Respostas 15
Participantes 4