Search code examples
javaswingpaintcomponentrepaint

Constant repaint issue


Background: I'm making a multiplayer game of "pictionary" or similar to " draw something."

Problem: When I draw freehand its constantly calling repaint(). when i press the button and click on the jpanel, the button is repainted or redrawn on the jpanel.

Code:

public class DrawP extends JPanel implements MouseListener, MouseMotionListener{
private int x1;
private int y1;
private int cx,cy;

public DrawP(){
    super();
    JFrame fr = new JFrame("Test");

    JButton btn = new JButton("Test");

    fr.setSize(500, 500);
    Container c = fr.getContentPane();
    c.add(btn, BorderLayout.SOUTH);
    c.add(this);
    this.addMouseListener(this);
    this.addMouseMotionListener(this);
    fr.setVisible(true);
    c.validate();
    c.repaint();
}

public void paintComponent(Graphics g){
    super.paintComponents(g);
    g.drawLine(cx, cy, x1, y1);
}
@Override
public void mouseDragged(MouseEvent e) {
    x1 = e.getX();
    y1 = e.getY();
    cx = x1; 
    cy = y1;
    repaint();
}

@Override
public void mouseMoved(MouseEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void mouseClicked(MouseEvent e) {
    // TODO Auto-generated method stub
    cx = e.getX();
    cy = e.getY();
    x1 = cx;
    y1 = cy;
    repaint();
}

@Override
public void mouseEntered(MouseEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void mouseExited(MouseEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void mousePressed(MouseEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void mouseReleased(MouseEvent e) {
    // TODO Auto-generated method stub

}

public static void main (String [] args){
    DrawP d = new DrawP();

}
}

This picture shows what happens after I click on the button and draw: https://i.sstatic.net/xMi7N.jpg


Solution

  • super.paintComponent's'(g);
    

    Looks like you have a typo. You don't want the "s" in paintComponent(...);

    c.validate();
    c.repaint();
    

    Also, you don't need the above two lines. The frame is revalidated and painted when you make the frame visible. The only time you use the revalidate() and repaint() methods is when you add/remove components from a visible GUI.

    Edit:

    it only shows a dot on the application

    If you want to do incremental painting then check out Custom Painting Approaches for example of the two common ways to do this:

    1. Use a List to keep track of all the lines to draw
    2. Draw directly onto a BufferedImage.