Problema Java 2d minimizar x maximizar [Resolvido]

12 respostas
Tomassoni

Galera estou usando uma JPanel com plano de fundo, e usando java 2d para desenhar sobre esse plano de fundo, porem, as linhas que desenho somem, ao minimizar e maximizar o JFrame, alguém poderia me ajudar?

12 Respostas

ViniGodoy

Todo desenho do JPanel deve ser feito dentro do método paintComponent. É ele que o Java chamará sempre que o painel for escondido/reexibido.

Tomassoni

Fiz assim.

Metodo que pega coordenadas do mouse

public void penOperation(MouseEvent e) {
        Graphics g = this.getGraphics();
        g.setColor(mainColor);

        /*
        In initial state setup default values
        for mouse coordinates
         */
        if (initialPen) {
            setGraphicalDefaults(e);
            initialPen = false;
            g.drawLine(prevx, prevy, mousex, mousey);
        }

        /*
        Make sure that the mouse has actually
        moved from its previous position.
         */
        if (mouseHasMoved(e)) {
            /*
            set mouse coordinates to
            current mouse position
             */
            mousex = e.getX();
            mousey = e.getY();

            /*
            draw a line from the previous mouse coordinates
            to the current mouse coordinates
             */
            g.drawLine(prevx, prevy, mousex, mousey);

            /*
            set the current mouse coordinates to
            previous mouse coordinates for next time
             */
            prevx = mousex;
            prevy = mousey;
        }

    }
@Override
    public void paintComponent(Graphics g) {     
        g.drawImage(img, 0, 0, this.width, this.height, this);     
        System.out.println("Paint");

    }

Como faria para colocar dentro do paintComponent ?

ViniGodoy

Crie atributos para prevx, prevy, mousex, mousey.

E então fraça aquele drawLine dentro do paintComponent.

@Override  
public void paintComponent(Graphics g) {       
   Graphics2D g2d = (Graphics2D) g.create();

   g2d.drawImage(img, 0, 0, this.width, this.height, this);       
   g2d.drawLine(prevx, prevy, mousex, mousey);

   System.out.println("Paint");  
   g2d.dispose();
}
Tomassoni

Cara não deu certo.

Esse é um rascunho que fiz.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package testes;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;

/**
 *
 * @author Tomassoni
 */
public class BackGroundPanel extends JPanel implements ActionListener, AdjustmentListener, MouseListener, MouseMotionListener {

    private Image img;
    private int width;
    private int height;
    private final int PEN_OP = 1;
    /* Current mouse coordinates */
    private int mousex = 0;
    private int mousey = 0;

    /* Previous mouse coordinates */
    private int prevx = 0;
    private int prevy = 0;
    /* Initial state falgs for operation */
    private boolean initialPen = true;
    private boolean initialPolygon = true;
    private boolean initialSpline = true;
    /* Main Mouse X and Y coordiante variables */
    private int Orx = 0;
    private int Ory = 0;
    private int OrWidth = 0;
    private int OrHeight = 0;
    private int drawX = 0;
    private int drawY = 0;
    private int eraserLength = 5;
    private int udefRedValue = 255;
    private int udefGreenValue = 255;
    private int udefBlueValue = 255;
    /* Primitive status & color variables */
    private int opStatus = PEN_OP;
    private int colorStatus = 1;
    private Color mainColor = new Color(0, 0, 0);
    private Color xorColor = new Color(255, 255, 255);
    private Color statusBarColor = new Color(166, 166, 255);
    private Color userDefinedColor = new Color(udefRedValue, udefGreenValue, udefBlueValue);

    public BackGroundPanel(Image img, int imgWidth, int imgHeight) {
        //this(new ImageIcon(img).getImage());
        this.img = img;
        this.width = imgWidth;
        this.height = imgHeight;

        System.out.println(this.width);
        System.out.println(this.height);

        Dimension size = new Dimension(this.width, this.height);
        setPreferredSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
        setSize(size);
        setLayout(null);
        this.setDoubleBuffered(true);

        System.out.println("Bkg" + this.getHeight());
        System.out.println("Bkg" + this.getWidth());

        this.addMouseListener(this);
        this.addMouseMotionListener(this);

    }

    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g.drawImage(img, 0, 0, this.width, this.height, this);
        System.out.println("PC");
        g2d.setColor(mainColor);
        g2d.drawImage(img, 0, 0, this.width, this.height, this);
        g2d.drawLine(prevx, prevy, mousex, mousey);

        System.out.println("Paint");
        //g2d.dispose();

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Pen")) {
            opStatus = PEN_OP;
        }
        initialPolygon = true;
        initialSpline = true;
        setMainColor();

    }

    public void adjustmentValueChanged(AdjustmentEvent e) {
        System.out.println("adjustmentValueChanged verifique");
    }

    public void mouseClicked(MouseEvent e) {
        updateMouseCoordinates(e);
    }

    public void mousePressed(MouseEvent e) {
        updateMouseCoordinates(e);
    }

    public void mouseReleased(MouseEvent e) {
        updateMouseCoordinates(e);
        releasedPen();
    }

    public void mouseEntered(MouseEvent e) {
        updateMouseCoordinates(e);
    }

    public void mouseExited(MouseEvent e) {
        updateMouseCoordinates(e);
    }

    public void mouseDragged(MouseEvent e) {
        updateMouseCoordinates(e);
        penOperation(e);
        repaint();
    }

    public void mouseMoved(MouseEvent e) {
        updateMouseCoordinates(e);
    }

    public void setMainColor() {
        mainColor = Color.black;
    }

    public void penOperation(MouseEvent e) {
        //Graphics g = this.getGraphics();
       // g.setColor(mainColor);

        /*
        In initial state setup default values
        for mouse coordinates
         */
        if (initialPen) {
            setGraphicalDefaults(e);
            initialPen = false;
            //g.drawLine(prevx, prevy, mousex, mousey);
        }

        /*
        Make sure that the mouse has actually
        moved from its previous position.
         */
        if (mouseHasMoved(e)) {
            /*
            set mouse coordinates to
            current mouse position
             */
            mousex = e.getX();
            mousey = e.getY();

            /*
            draw a line from the previous mouse coordinates
            to the current mouse coordinates
             */
            //g.drawLine(prevx, prevy, mousex, mousey);

            /*
            set the current mouse coordinates to
            previous mouse coordinates for next time
             */
            prevx = mousex;
            prevy = mousey;
        }

    }

    /*
    Method determines weather the mouse has moved
    from its last recorded position.
    If mouse has deviated from previous position,
    the value returned will be true, otherwise
    the value that is returned will be false.
     */
    public boolean mouseHasMoved(MouseEvent e) {
        return (mousex != e.getX() || mousey != e.getY());
    }

    /*
    Method is a key segment in the operations where
    there are more than 2 variables deviating to
    makeup a graphical operation.
    This method calculates the new values for the
    global varibles drawX and drawY according to
    the new positions of the mouse cursor.
    This method eleviates the possibility that
    a negative width or height can occur.
     */
    public void setActualBoundry() {

        /*
        If the any of the current mouse coordinates
        are smaller than the origin coordinates, meaning
        if drag occured in a negative manner, where either
        the x-shift occured from right and/or y-shift occured
        from bottom to top.
         */
        if (mousex < Orx || mousey < Ory) {

            /*
            if the current mouse x coordinate is smaller
            than the origin x coordinate,
            equate the drawX to be the difference between
            the current width and the origin x coordinate.
             */
            if (mousex < Orx) {
                OrWidth = Orx - mousex;
                drawX = Orx - OrWidth;
            } else {
                drawX = Orx;
                OrWidth = mousex - Orx;

            }

            /*
            if the current mouse y coordinate is smaller
            than the origin y coordinate,
            equate the drawY to be the difference between
            the current height and the origin y coordinate.
             */
            if (mousey < Ory) {
                OrHeight = Ory - mousey;
                drawY = Ory - OrHeight;
            } else {
                drawY = Ory;
                OrHeight = mousey - Ory;
            }

        } /*
        Else if drag was done in a positive manner meaning
        x-shift occured from left to right and or y-shift occured
        from top to bottom
         */ else {
            drawX = Orx;
            drawY = Ory;
            OrWidth = mousex - Orx;
            OrHeight = mousey - Ory;
        }

    }

    /*
    Method sets all the drawing varibles to the default
    state which is the current position of the mouse cursor
    Also the height and width varibles are zeroed off.
     */
    public void setGraphicalDefaults(MouseEvent e) {
        mousex = e.getX();
        mousey = e.getY();
        prevx = e.getX();
        prevy = e.getY();
        Orx = e.getX();
        Ory = e.getY();
        drawX = e.getX();
        drawY = e.getY();
        OrWidth = 0;
        OrHeight = 0;
    }

    /*
    Method displays the mouse coordinates x and y values
    and updates the mouse status bar with the new values.
     */
    public void updateMouseCoordinates(MouseEvent e) {
        String xCoor = "";
        String yCoor = "";

        if (e.getX() < 0) {
            xCoor = "0";
        } else {
            xCoor = String.valueOf(e.getX());
        }

        if (e.getY() < 0) {
            xCoor = "0";
        } else {
            yCoor = String.valueOf(e.getY());
        }

        //System.out.println("x:" + xCoor + "   y:" + yCoor);

    }

    /*
    Method is invoked when mouse has been released
    and current operation is Pen
     */
    public void releasedPen() {
        initialPen = true;
        System.out.println("Soltou");
        // repaint();
    }
}//Fim da classe

Poderia me ajudar encontrar a falha
O mesmo acontence com esse exemplo na net.
http://www.ccs.neu.edu/home/carlyh/i4/Paint.html
desenhe algo e arraste qualquer janela sobre o desenho, ou minimize e maximize o navegador. So que o meu e j2se.

ViniGodoy

Rodei sua aplicação aqui e agora entendi o que ela faz.

Bom, você tem que entender que tudo que é desenhado no JPanel não é guardado na memória. Fica apenas na memória de vídeo. Uma vez apagado, foi-se para sempre.

Por isso, você tem duas alternativas:
a) Desenhar num BufferedImage, e no método paintComponent, só plotar esse BufferedImage na tela;
b) Gravar a coordenada de todos os pontos desenhados, e depois redesenha-los.

No seu caso, como é para se parecer com um Paint, a alternativa a) é a mais viável. Até pq, é a que exigirá menor número de modificações no seu código. Dê uma olhada:

package teste;  
   
 import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
   
 /** 
 * 
 * @author Tomassoni 
 */  
 public class BackGroundPanel extends JPanel implements ActionListener, AdjustmentListener {  
   
	 //Representa a imagem sendo desenhada
	 private BufferedImage img;
	 
     private int width;  
     private int height;  
     private final int PEN_OP = 1;  
     /* Current mouse coordinates */  
     private int mousex = 0;  
     private int mousey = 0;  
   
     /* Previous mouse coordinates */  
     private int prevx = 0;  
     private int prevy = 0;  
     /* Initial state falgs for operation */  
     private boolean initialPen = true;  
     private boolean initialPolygon = true;  
     private boolean initialSpline = true;  
     /* Main Mouse X and Y coordiante variables */  
     private int Orx = 0;  
     private int Ory = 0;  
     private int OrWidth = 0;  
     private int OrHeight = 0;  
     private int drawX = 0;  
     private int drawY = 0;  
     private int eraserLength = 5;  
     private int udefRedValue = 255;  
     private int udefGreenValue = 255;  
     private int udefBlueValue = 255;  
     /* Primitive status & color variables */  
     private int opStatus = PEN_OP;  
     private int colorStatus = 1;  
     private Color mainColor = new Color(0, 0, 0);  
     private Color xorColor = new Color(255, 255, 255);  
     private Color statusBarColor = new Color(166, 166, 255);  
     private Color userDefinedColor = new Color(udefRedValue, udefGreenValue, udefBlueValue);  
   
     public BackGroundPanel(BufferedImage img) {
    	 
    	 //Fazemos uma cópia da imagem, para não destruir a original
         this.img = new BufferedImage(img.getWidth(null), img.getHeight(null), 
        		 img.getType() == BufferedImage.TYPE_CUSTOM ? BufferedImage.TYPE_INT_ARGB : img.getType());
         
         this.width = img.getWidth();  
         this.height = img.getHeight();  
   
         Dimension size = new Dimension(this.width, this.height);  
         setPreferredSize(size);  
         setMinimumSize(size);  
         setMaximumSize(size);  
         setSize(size);
         setLayout(null);  
         
         MouseHandler handler = new MouseHandler();
         addMouseListener(handler);  
         addMouseMotionListener(handler);  
     }  
   
     @Override  
     public void paintComponent(Graphics g) {  
         Graphics2D g2d = (Graphics2D) g.create();
         
         //Aqui só desenhamos a imagem
         g.drawImage(img, 0, 0, this.width, this.height, this);
         
         g2d.dispose();  
     }  
   
     @Override  
     public void actionPerformed(ActionEvent e) {  
         if (e.getActionCommand().equals("Pen")) {  
             opStatus = PEN_OP;  
         }  
         initialPolygon = true;  
         initialSpline = true;  
         setMainColor();  
   
     }  
   
     public void adjustmentValueChanged(AdjustmentEvent e) {  
         System.out.println("adjustmentValueChanged verifique");  
     }  
   
     private class MouseHandler implements MouseListener, MouseMotionListener {
	     public void mouseClicked(MouseEvent e) {  
	         updateMouseCoordinates(e);  
	     }  
	   
	     public void mousePressed(MouseEvent e) {  
	         updateMouseCoordinates(e);  
	     }  
	   
	     public void mouseReleased(MouseEvent e) {  
	         updateMouseCoordinates(e);  
	         releasedPen();  
	     }  
	   
	     public void mouseEntered(MouseEvent e) {  
	         updateMouseCoordinates(e);  
	     }  
	   
	     public void mouseExited(MouseEvent e) {  
	         updateMouseCoordinates(e);  
	     }  
	   
	     public void mouseDragged(MouseEvent e) {  
	         updateMouseCoordinates(e);  
	         penOperation(e);  
	         repaint();  
	     }  
	   
	     public void mouseMoved(MouseEvent e) {  
	         updateMouseCoordinates(e);  
	     }
     }
   
     public void setMainColor() {  
         mainColor = Color.black;  
     }  
   
     public void penOperation(MouseEvent e) {
    	 //Escrevemos sobre a imagem
         Graphics2D g = img.createGraphics();  
         g.setColor(mainColor);  
   
         /* 
         In initial state setup default values 
         for mouse coordinates 
          */  
         if (initialPen) {  
             setGraphicalDefaults(e);  
             initialPen = false;  
             g.drawLine(prevx, prevy, mousex, mousey);  
         }  
   
         /* 
         Make sure that the mouse has actually 
         moved from its previous position. 
          */  
         if (mouseHasMoved(e)) {  
             /* 
             set mouse coordinates to 
             current mouse position 
              */  
             mousex = e.getX();  
             mousey = e.getY();  
   
             /* 
             draw a line from the previous mouse coordinates 
             to the current mouse coordinates 
              */  
             g.drawLine(prevx, prevy, mousex, mousey);  
   
             /* 
             set the current mouse coordinates to 
             previous mouse coordinates for next time 
              */  
             prevx = mousex;  
             prevy = mousey;  
         }  
         
         g.dispose();
     }  
   
     /* 
     Method determines weather the mouse has moved 
     from its last recorded position. 
     If mouse has deviated from previous position, 
     the value returned will be true, otherwise 
     the value that is returned will be false. 
      */  
     public boolean mouseHasMoved(MouseEvent e) {  
         return (mousex != e.getX() || mousey != e.getY());  
     }  
   
     /* 
     Method is a key segment in the operations where 
     there are more than 2 variables deviating to 
     makeup a graphical operation. 
     This method calculates the new values for the 
     global varibles drawX and drawY according to 
     the new positions of the mouse cursor. 
     This method eleviates the possibility that 
     a negative width or height can occur. 
      */  
     public void setActualBoundry() {  
   
         /* 
         If the any of the current mouse coordinates 
         are smaller than the origin coordinates, meaning 
         if drag occured in a negative manner, where either 
         the x-shift occured from right and/or y-shift occured 
         from bottom to top. 
          */  
         if (mousex &lt; Orx || mousey &lt; Ory) {  
   
             /* 
             if the current mouse x coordinate is smaller 
             than the origin x coordinate, 
             equate the drawX to be the difference between 
             the current width and the origin x coordinate. 
              */  
             if (mousex &lt; Orx) {  
                 OrWidth = Orx - mousex;  
                 drawX = Orx - OrWidth;  
             } else {  
                 drawX = Orx;  
                 OrWidth = mousex - Orx;  
   
             }  
   
             /* 
             if the current mouse y coordinate is smaller 
             than the origin y coordinate, 
             equate the drawY to be the difference between 
             the current height and the origin y coordinate. 
              */  
             if (mousey &lt; Ory) {  
                 OrHeight = Ory - mousey;  
                 drawY = Ory - OrHeight;  
             } else {  
                 drawY = Ory;  
                 OrHeight = mousey - Ory;  
             }  
   
         } /* 
         Else if drag was done in a positive manner meaning 
         x-shift occured from left to right and or y-shift occured 
         from top to bottom 
          */ else {  
             drawX = Orx;  
             drawY = Ory;  
             OrWidth = mousex - Orx;  
             OrHeight = mousey - Ory;  
         }  
   
     }  
   
     /* 
     Method sets all the drawing varibles to the default 
     state which is the current position of the mouse cursor 
     Also the height and width varibles are zeroed off. 
      */  
     public void setGraphicalDefaults(MouseEvent e) {  
         mousex = e.getX();  
         mousey = e.getY();  
         prevx = e.getX();  
         prevy = e.getY();  
         Orx = e.getX();  
         Ory = e.getY();  
         drawX = e.getX();  
         drawY = e.getY();  
         OrWidth = 0;  
         OrHeight = 0;  
     }  
   
     /* 
     Method displays the mouse coordinates x and y values 
     and updates the mouse status bar with the new values. 
      */  
     public void updateMouseCoordinates(MouseEvent e) {  
         String xCoor = "";  
         String yCoor = "";  
   
         if (e.getX() &lt; 0) {  
             xCoor = "0";  
         } else {  
             xCoor = String.valueOf(e.getX());  
         }  
   
         if (e.getY() &lt; 0) {  
             xCoor = "0";  
         } else {  
             yCoor = String.valueOf(e.getY());  
         }  
   
         //System.out.println("x:" + xCoor + "   y:" + yCoor);  
   
     }  
   
     /* 
     Method is invoked when mouse has been released 
     and current operation is Pen 
      */  
     public void releasedPen() {  
         initialPen = true;  
         System.out.println("Soltou");  
         invalidate();  
     }       
 }//Fim da classe
Tomassoni

Entendi, estava batendo cabeça. Obrigado pela atenção. Poderia so por gentileza, me dizer como buferizou a imagem a minha esta ficando preta.Estou fazendo assim

Image imag = new ImageIcon(resourceMap.getString("background.image")).getImage();
bimage = new BufferedImage(image.getWidth(null), imag.getHeight(null), BufferedImage.TYPE_INT_RGB);
ViniGodoy
Tomassoni

É consegui, só que aconteceu um lance aqui, a imagem ficava preta, resgatei meu livro do Deitel, li todo o capitulo a respeito, e não cheguei a uma conclusão.
Porem comentei uma parte e deu certo.

public BackGroundPanel(BufferedImage img) {
        //Fazemos uma cópia da imagem, para não destruir a original
        this.img = img;
        //new BufferedImage(img.getWidth(null), img.getHeight(null),
        //img.getType() == BufferedImage.TYPE_CUSTOM ? BufferedImage.TYPE_INT_ARGB : img.getType());
        this.width = img.getWidth();
        this.height = img.getHeight();

Comentei essa parte e funcionou, consigo desenhar sobre a imagem, sem afetar a original, e imprimo ela com os desenhos que fiz sobre.

Só tenho mais uma duvida, se puder me ajudar.
Antes, quando estava com mais problemas, a imagem era redimensionada do tamanho do jpanel, agora ela fica no seu tamanho real, e se tento alinhar ela no jpanel
posicao x e y ? e !, a ela alinha porem fica recortada, some o pedaço dela exatamente proporcional ao x e y definido. Sabe como eu corrijo isso?
E tambem, como posso fazer para salvar essa imagem após desenhada ao inves de imprimir ?

g.drawImage(img, ?, !, this.width, this.height, this);

Agradeço novamente, e o livro do Deitel não me ajudou muito não, ele e bem resumido no capitulo sobre o assunto.

ViniGodoy

Não entendi pq sua imagem fica preta. Ela provavelmente não pode ser convertida para ARGB.
Que formato de imagem você está usando?

Você quer que a imagem se estique para o tamanho do painel?
Nesse caso, use esse drawImage aqui. Passe para ele as coordenadas da imagem e do painel.

É uma boa também ler esse tutorial:
http://java.sun.com/docs/books/tutorial/2d/TOC.html

Ele explica bastante no Java 2D. E dá uma olhadinha nessas classes também:
http://www.guj.com.br/posts/list/56248.java#295271
http://www.guj.com.br/posts/list/77265.java#408245

Por fim, eu recomendo a leitura desse material aqui:
http://fivedots.coe.psu.ac.th/~ad/jg/ch04/index.html

Tomassoni

Cara, obrigado mesmo.
Muito bom os materiais, tudo resolvido.
Para salvar a imagem é tão fácil.

ImageIO.write(this.img, "PNG", new File(imagesDir + "Teste.png"));
ViniGodoy

Bom, vai ter muito material sobre Java 2D em português no site que vou inaugurar de desenvolvimento de jogos.
Dia primeiro coloco o link aqui. Ele vai substituir esse site que está na minha assinatura. :wink:

Aí espero sua visita por lá.

[MARKETING DETECTED :lol: ]

Tomassoni

Legal, vou aguardar.
Estou em projeto que vai usar muita manipulação de imagens.
Até breve.

Criado 23 de outubro de 2009
Ultima resposta 24 de out. de 2009
Respostas 12
Participantes 2