Problema com paint [RESOLVIDO]

Boas noites

Quando redimensiono a janela, os desenhos desaparecem

public class Teste extends JPanel{
    public void paint(Graphics g){
        super.paint(g);
        setBackground(Color.WHITE);
        g.drawLine(30, 30, 10, 200);
    }
}

public void desenhar(Graphics g, int erro){
        if(erro == 1){           
            g.fillRect(324, 244, 200, 300);
        }else if(erro == 2){
            g.fillOval(300, 100, 80, 100);
        }
    }
public class NewClass extends JFrame implements ActionListener{
...
public void actionPerformed(ActionEvent e) {
        if(bt == e.getSource()){
            erro++;
            teste = new Teste();
            teste.desenhar(getGraphics(), erro);
        }
}

Eu já vi aqui no fórum que tenho de usar BufferedImage mas não estou a conseguir, quando uso BufferedImage ele não desenha nada no inicio e ao carregar no botão tb não aparece nada…
Como poderei fazer?

Grato

Chame o método repaint do JPanel após desenhar algo, acho q isso resolverá o seu problema

1° Sobreescreva o método paintComponent e nao o paint do JPanel.
2° crie uma cópia do Graphics para trabalhar.

public class Teste extends JPanel{
    public void paint(Graphics g){
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setBackground(Color.WHITE);
        g2d.drawLine(30, 30, 10, 200);
        g2d.dispose();
    }
}

public void desenhar(Graphics g, int erro){
        if(erro == 1){           
            g.fillRect(324, 244, 200, 300);
        }else if(erro == 2){
            g.fillOval(300, 100, 80, 100);
        }
    }

E lembre-se de fazer a copia no método desenhar também e o dispose no final.

O JPanel não guarda status do que foi desenhado. Então, você tem duas alternativas:

a) Redesenhar tudo, no método paintComponent. Esteja preparado para tudo ser redesenhado.
b) Desenhar tudo numa BufferedImage, e então desenhar essa imagem no paintComponent.

Você comentou que tentou fazer do jeito b). Pode postar o seu código para vermos qual é o problema?

Ora bom dia:D

Então fiz assim…

public class Teste extends JPanel {
     BufferedImage img = new BufferedImage(600, 600, BufferedImage.TYPE_INT_ARGB);
     
     public void paintComponent(Graphics2D g) {
        super.paintComponent(g);
        g.drawImage(img, 0, 0, null);
    }
    public void desenhar(int erro) {
        Graphics2D g = (Graphics2D) img.getGraphics().create();
        if (erro == 1) {
            g.fillRect(324, 244, 200, 300);
        } else if (erro == 2) {
            g.fillOval(300, 100, 80, 100);
        }
        g.dispose();
    }

Grato

E assim não funcionou?

Não :frowning: nao aparece nada … :roll:
O que está mal? :?

Grato

Troquei uma coisita e já aparece no inicio, mas quando carrego no botão não desenha.
Então está assim.

public class Teste extends JPanel {
    BufferedImage img = new BufferedImage(700, 700, BufferedImage.TYPE_INT_ARGB);
    public void paintComponent(Graphics g) { // alterei aqui estava (Graphics2D g) agora pinta no inico
        super.paintComponent(g);
        setBackground(Color.WHITE);
        g.fillOval(100, 100, 200, 200);
        g.drawImage(img, 0, 0, null);
    }
     public void desenhar(int erro) { // isto não está a fazer nada
        Graphics2D g = (Graphics2D) img.getGraphics().create();
        if (erro == 1) {
            g.fillRect(324, 244, 200, 300);
        } else if (erro == 2) {
            g.fillOval(300, 100, 80, 100);
        }     
    }
public class NewClass extends JFrame implements ActionListener{
     public NewClass(){
        setLayout(new BorderLayout());
        teste= new Teste();
        add(teste, BorderLayout.CENTER);
        add(botoes(), BorderLayout.SOUTH);
        setSize(1400, 600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
...
    public void actionPerformed(ActionEvent e) {
        if(bt == e.getSource()){
            erro++;
            teste.desenhar(erro);
        }
}

Seu método desenhar tem que avisar o resto do mundo que o painel mudou. Senão ele não se repintará:

public void desenhar(int erro) { Graphics2D g = img.createGraphics(); if (erro == 1) { g.fillRect(324, 244, 200, 300); } else if (erro == 2) { g.fillOval(300, 100, 80, 100); } g.dispose(); repaint(); //Informa que o painel deve ser redesenhado }

Seu paintComponent também precisa fazer a cópia do contexto gráfico, antes de utiliza-lo:

public void paintComponent(Graphics g) { super.paintComponent(g); Graphics g2d = (Graphics2D)g.create(); //Faz a cópia g2d.setBackground(Color.WHITE); g2d.fillOval(100, 100, 200, 200); g2d.drawImage(img, 0, 0, null); g2d.dispose(); //libera a cópia }

Bom Dia,

Vini não percebo fiz copy paste do que vc postou e não funciona na mesma :?
O que poderá ser??? :cry:

Grato

Tenta chamar também invalidate() antes do repaint(). Não creio que isso resolve.

Anexe o código todo num zip aqui, e eu baixo para dar uma olhada.

Só uma dúvida… você por acaso adicionou seu frame como actionListener do botão?

botao.addActionListener(this)

sim :stuck_out_tongue:

Ora cá vai

Obrigado mais uma vez

Tem vários erros no código que você me passou:

  1. No ActionListener do seu botão, você faz:
    teste = new Teste();

Isso cria um painel novo. Logo, você não está chamando o método desenhar no mesmo painel que você adicionou no JFrame.

  1. Na sua classe Teste, o construtor do BufferedImage está com os dois primeiros parâmetros com valores iguais a 1:
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);

Como você espera desenhar uma forma qualquer em apenas 1 pixel?

Segue o código todo corrigido:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class NewClass extends JFrame {

    private JButton btJogar, btNovo;
    private JPanel panel;
    private Teste teste;

    public NewClass() {
        setLayout(new BorderLayout());
        teste = new Teste();

        add(teste, BorderLayout.CENTER);
        add(botoes(), BorderLayout.SOUTH);
        setTitle("Teste");
        setSize(1400, 600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public JPanel botoes() {
        panel = new JPanel();
        panel.setBackground(Color.red);

        btJogar = new JButton("OK");
        btJogar.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                desenhar();
            }
        });


        btNovo = new JButton("Novo");
        btNovo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                novo();
            }
        });

        panel.add(btJogar);
        panel.add(btNovo);
        return panel;
    }
    int erro = 0;

    public void desenhar() {
        erro++;
        teste.desenhar(erro);
    }

    public void novo() {
    }

    public static void main(String[] args) {
        new NewClass();
    }
}
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

public class Teste extends JPanel {
    BufferedImage img = null;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics g2d =  g.create(); //Faz a cópia
        g2d.fillOval(100, 100, 200, 200);
        g2d.drawImage(img, 0, 0, null);
        g2d.dispose(); //libera a cópia
    }

    public void desenhar(int erro) {
        if (img == null)  {
            img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
        }
        
        Graphics2D g = img.createGraphics();
        if (erro == 1) {
            g.fillRect(324, 244, 200, 300);
        } else if (erro == 2) {
            g.fillOval(300, 100, 80, 100);
        }
        g.dispose();
        repaint(); 
    }
}

Muito Obrigado vini :slight_smile: :slight_smile: :slight_smile: