Olá, sou novo aqui no fórum e estou tendo um problema com um JPanel. Minha aplicação funciona da seguinte maneira: um JFrame contem um JPanel que é utilizado como uma área de desenho.
Estou conseguindo desenhar, mas após acabar o desenho, se eu mexo o cursor dentro do JPanel o desenho desaparece. Alguém poderia me dar alguma dica?
Obrigado
Problema com JPanel apagando imagem
14 Respostas
Oi edu12345,
Espero que ajude:http://silveiraneto.net/2008/01/15/desenhando-com-java-e-netbeans/
Legal o tutorial, mas ainda não resolveu o meu problema. A aplicação será utilizada para fazer desenhos, então queria achar uma maneira de inserir objetos graficos no Graphics do JPanel dinamicamente, ou seja, enquanto o programa estiver rodando.
Li em algum lugar a respeito de Buffers de Graphics, mas não sei se é a melhor solução.
O JPanel chama o método repaint() após alguma alteração na janela (maximizar, ocultar, exibir…).
Para manter o desenho você precisa salva-lo em memória para refaze-lo na sobrescrita do método repaint().
Para isto mantenha as coordenadas em um array de objetos Point.
O livro Java como Programar, capítulo 11, página 410, tem um exemplo muito bom.
Você quer fazer um prog… como o paint?
Valeu pelas dicas! Vou dar uma olhada no livro. A finalidade do programa é desenhar circuitos. Estou fazendo mais para aprender mesmo, já que um programa assim necessita de vários conhecimentos. Mais uma vez, obrigado pelas dicas!

bzy, nem precisei olhar no livro! a idéia que você me deu funcionou perfeitamente! obrigado!
Estamos ai pra isso. 
Primeiro de tudo.
Sempre que você precisar pintar um painel, você deve sobrescrever o método paintComponent não repaint() ou paint(). Isso aqui é recomendado aqui: http://java.sun.com/products/jfc/tsc/articles/painting/#swing
É importante também tirar uma cópia do seu contexto gráfico, antes de iniciar o desenho:
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
//Código aqui
g2d.dispose();
}
O paintComponent é chamado sempre que o Swing precisa repintar a janela.
Por fim, recomendo os seguintes tutoriais, para compreender melhor o Java2D e suas potencialidades:
Ponto V! - Uma visão rápida do Java 2D
Ponto V! - Pintando no Java 2D!
Ponto V! - O fantasma do Pacman
Ponto V! - Trabalhando com imagens
NUNCA sobrescreva repaint() ou paint(). Apesar de ter “funcionado” esses métodos geralmente geram comportamentos inconsistentes e pouco otimizados e bugs muito difíceis de corrigir.
Só um outro comentário. O JPanel e o Graphics não guardam estado. Há duas maneiras de não perder o que é desenhado:
- Criar uma lista de objetos a serem desenhados. E então pinta-los sempre que o método paintComponent for chamado.
- Desenhar sobre uma BufferedImage, e só repintar essa imagem no paintComponent;
A opção 1 provavelmente é a melhor no seu caso. Você precisará guardar os circuitos existentes e suas propriedades, e dar a possibilidade de mover alguns circuitos ou deletá-los. Portanto, você já terá que guardar estado do que está desenhado de um jeito ou de outro.
A opção 2 é melhor se você estiver montando um paint. Usa-se um componente temporário, até que o usuário confirme o desenho. Após isso, copia-se o desenho final para o BufferedImage e o componente original feito para desenha-lo é “esquecido”. Não é mais possível redimensionar uma forma posicionada na tela.
O objeto Graphics não é a área de pintura. Uma analogia mais correta para ele seria a “caneta”. Nele você configura a intensidade do desenho, a cor e o formato do traço. Além disso, você configura se irá desenhar sobre o “papel” de pé ou inclinado.
BZY qual a edição do livro, pois java - como programar existem várias edições e qual o assunto?!Estou com o mesmo problema…
É só usar uma das opções que descrevi.
Então essa List é do ArrayList e vc coloca a imagem(Image) dentro do ArrayList, será que funciona?!
As duas opções funcionam. A primeira é criar uma lista de Shapes, não de Image. A segunda, é desenhar sobre um BufferedImage e ao final desenhar só essa imagem na tela.
De um exemplo de cada um, não estou conseguindo entender…