[resolvido]repaint() causa problema na frame

9 respostas
M

Meu projeto possui uma frame com 2 panels, o primeiro Formas que possui alguns radiobuttons pra selecionar uma opção, adicionado no BorderLayout.NORTH da frame, e outro que é a Tela adicionado no BorderLayout.CENTER da frame. O panel Tela deve pintar o pixel que o usuário clicar, e para isso estou usando mousehandler e mouselistener para pegar o x e y de onde foi clicado, e quando feito isso chamo a função repaint para desenhar o ponto. O problema é que quando chamado a função repaint a frame fica com o desenho do panel Forma duplicado, 1 vez onde deveria estar, e outra sobre o panel Tela. Quando redimensionada a frame a duplicação desaparece junto com todos os pontos desenhados.

Função paintComponent

public void paintComponent (Graphics g){
        super.paintComponents(g);
        g.setColor(Color.BLACK);
        g.drawLine(x, y, x, y);
    }

Função onde chamo o repaint (função dentro da subclasse MouseHandler que implementa MouseListener)

public void mousePressed(MouseEvent e) {
            x = e.getX();
            y = e.getY();
            repaint();
        }

Codigo da minha frame

import java.awt.BorderLayout;
import javax.swing.JFrame;

public class Janela extends JFrame {
    private Tela tela;
    private Formas formas;

    public Janela() {
        super("Trabalho CG");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 600);
        formas = new Formas();
        tela = new Tela();
        add(tela, BorderLayout.CENTER);
        add(formas, BorderLayout.NORTH);
    }

Imagens do programa em execução mostrando o bug
tela inicial
http://img148.imageshack.us/i/figura1hj.jpg/
depois de 1 repaint
http://img33.imageshack.us/i/figura2vc.jpg/
depois de varios repaint
http://img843.imageshack.us/i/figura3l.jpg/

9 Respostas

H

Boa Noite,

Só uma dúvida, vc está repintando a tela toda ou só um componente? Tenta usar um repaint em todo o frame, ou um revalidate, o swing de vez em quando se comporta de forma misteriosa quanto a isso (ao menos misteriosa pra mim) :slight_smile:

C

mauricio1989:
Meu projeto possui uma frame com 2 panels, o primeiro Formas que possui alguns radiobuttons pra selecionar uma opção, adicionado no BorderLayout.NORTH da frame, e outro que é a Tela adicionado no BorderLayout.CENTER da frame. O panel Tela deve pintar o pixel que o usuário clicar, e para isso estou usando mousehandler e mouselistener para pegar o x e y de onde foi clicado, e quando feito isso chamo a função repaint para desenhar o ponto. O problema é que quando chamado a função repaint a frame fica com o desenho do panel Forma duplicado, 1 vez onde deveria estar, e outra sobre o panel Tela. Quando redimensionada a frame a duplicação desaparece junto com todos os pontos desenhados.

Função paintComponent

public void paintComponent (Graphics g){
        super.paintComponents(g);
        g.setColor(Color.BLACK);
        g.drawLine(x, y, x, y);
    }

Função onde chamo o repaint (função dentro da subclasse MouseHandler que implementa MouseListener)

public void mousePressed(MouseEvent e) {
            x = e.getX();
            y = e.getY();
            repaint();
        }

Codigo da minha frame

import java.awt.BorderLayout;
import javax.swing.JFrame;

public class Janela extends JFrame {
    private Tela tela;
    private Formas formas;

    public Janela() {
        super("Trabalho CG");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 600);
        formas = new Formas();
        tela = new Tela();
        add(tela, BorderLayout.CENTER);
        add(formas, BorderLayout.NORTH);
    }

Imagens do programa em execução mostrando o bug
tela inicial
http://img148.imageshack.us/i/figura1hj.jpg/
depois de 1 repaint
http://img33.imageshack.us/i/figura2vc.jpg/
depois de varios repaint
http://img843.imageshack.us/i/figura3l.jpg/

se vc estiver desenhando num jpanel, use updateUI() ao inves de repaint
mais informaçoes
http://www.guj.com.br/java/236416-desenhando-com-o-mouse-em-java

M

henriquehsv estou pintando apenas um componente.

ChronosSage estou desenhando em um jpanel, troquei o repaint() pelo updateUI e continua o mesmo problema.

O desenho está saindo da maneira que eu quero, o problema é que ele está colocando a imagem do jpanel formas no topo do jpanel tela, como pode ver nas imagens que postei. Aquela área onde o fica o erro continua sendo uma área possível de desenhar, mas com aquele fundo, não sei por que, nem como resolver.

Esse link que você postou, e em outros que eu pesquisei não encontrei exemplos do meu problema, ou 2 jpanel na mesma frame, desenhando em 1 deles.

PS: tentei mudar o modo que do add nos jpanels na frame para

Container pane = getContentPane(); pane.add(formas, BorderLayout.NORTH); pane.add(tela, BorderLayout.CENTER);
mas também não funcionou.

C

N notei problemas nos codigos q vc postou, axo q o problema esta na classe formas, posta o seu codigo completo para q eu possa ajuda-lo

M

classe Janela

package trabcg;

import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JFrame;

/**
 *
 * @author Mauricio Begnini
 */
public class Janela extends JFrame {
    private Tela tela;
    private Formas formas;

    public Janela() {
        super("Trabalho CG");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 600);
        formas = new Formas();
        tela = new Tela();
        Container pane = getContentPane();
        pane.add(formas, BorderLayout.NORTH);
        pane.add(tela, BorderLayout.CENTER);
    }

}

classe Tela

package trabcg;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;

/**
 *
 * @author Mauricio Begnini
 */
public class Tela extends JPanel {
    
    int x=-50;
    int y=-50;
    private int xIni;
    private int yIni;
    private int xFin;
    private int yFin;

    public Tela() {
        MouseHandler handler = new MouseHandler();
        addMouseListener(handler);
    }

    public void paintComponent (Graphics g){
        super.paintComponents(g);
        g.setColor(Color.BLACK);
        g.drawLine(x, y, x, y);
    }


        public class MouseHandler implements MouseListener {

        public void mouseClicked(MouseEvent e) {

        }

        public void mousePressed(MouseEvent e) {
            xIni = e.getX();
            yIni = e.getY();
            x = xIni;
            y = yIni;
            updateUI();
            System.out.print("["+xIni+", "+yIni+"]");
        }

        public void mouseReleased(MouseEvent e) {
            xFin = e.getX();
            yFin = e.getY();
            x = xFin;
            y = yFin;
            updateUI();
            System.out.println("["+xFin+", "+yFin+"]");
        }

        public void mouseEntered(MouseEvent e) {}

        public void mouseExited(MouseEvent e) {}

    }
}

classe Formas

package trabcg;

import java.awt.Color;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

/**
 *
 * @author Mauricio Begnini
 */
public class Formas extends JPanel {

    private JRadioButton reta;
    private JRadioButton circulo;
    private JRadioButton elipse;
    private ButtonGroup grupo;

    public Formas (){
        setBackground(Color.WHITE);
        reta = new JRadioButton("Reta");
        circulo = new JRadioButton("Circulo");
        elipse = new JRadioButton("Elipse");
        grupo = new ButtonGroup();
        reta.setBackground(Color.WHITE);
        circulo.setBackground(Color.WHITE);
        elipse.setBackground(Color.WHITE);
        grupo.add(reta);
        grupo.add(circulo);
        grupo.add(elipse);
        add(reta);
        add(circulo);
        add(elipse);
    }

}
ViniGodoy

ChronosSage:
se vc estiver desenhando num jpanel, use updateUI() ao inves de repaint
mais informaçoes http://www.guj.com.br/java/236416-desenhando-com-o-mouse-em-java

Por que usar o UpdateUI no lugar do repaint? Nunca vi nenhum motivo para isso. O updateUI geralmente é usado para atualizar o look&feel, conforme o próprio javadoc indica:
http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/JPanel.html#updateUI()

O evento correto para se usar ao solicitar um painel a ser repintado é o invalidate() ou, se há necessidade de se fazer isso imediatamente, o revalidate().

De qualquer forma, também não identifiquei nenhum erro aparente no código do colega, exceto talvez o fato dele não fazer cópias de contextos gráficos antes de altera-los. Entretanto, isso não deveria gerar esse comportamento bizarro.

C

achei o problema

onde ta

public void paintComponent (Graphics g){ super.paintComponents(g); g.setColor(Color.BLACK); g.drawLine(x, y, x, y); }
deveria ser

public void paintComponent (Graphics g){ super.paintComponent(g); g.setColor(Color.BLACK); g.drawLine(x, y, x, y); }

ViniGodoy

Putz, bem observado. "s"zinho fatal. :slight_smile:

M

valeu, problema resolvido

Criado 28 de março de 2011
Ultima resposta 1 de abr. de 2011
Respostas 9
Participantes 4