lsxliron
lsxliron

Reputation: 540

JFrame duplicates drawings when resizing

I wrote a code in Java (using swing) which draws few polygons on a panel.

public MyClass extends JPanel

The code is very simple (but long) and basically adds few Polygons, then adds few points to each polygon and then draw them on the screen (with drawPolygon).

My problem is when I run the program, I can't see the drawings on the panel. After a while, I figure out that when I re-size my frame, I can suddenly see the drawing but it duplicates itself many times (depends how much I re-size). If I play enough time with the resizing, I get:

 java.lang.OutOfMemoryError: Java heap space

Also, myPolygon.invalidate() doesn't help.

When using setResizable(false) I can't see my drawing at all.

Does anyone have a solution?

Duplicate Image Screenshot:1

Upvotes: 0

Views: 287

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

To start with, in your paintComponent method, don't call

setPreferredSize(new Dimension(500,500));
setVisible(true);
validate();

This will request a repaint, cause paintComponent to be recalled and you'll end up in a nasty loop, consuming your CPU and (as you have found out), your memory.

IF you can get away with it, you're better off to draw the polygon to a buffer and draw the buffer to the screen on each iteration of the paintComponent. This will be faster in the long run...

// Create a field
private BufferedImage buffer;

// Call this when you need to change the polygon some how...
protected void createBuffer() {

    // You need to determine the width and height values ;)
    buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = image.createGraphics();

    int xoffset=5;//Multiply in order to "zoom" the picture
    int offset=0;//moves shape to the right

    p.addPoint(40*xoffset-offset, 30*xoffset-offset);
    p.addPoint(50*xoffset-offset,30*xoffset-offset);
    p.addPoint(57*xoffset-offset,37*xoffset-offset);
    p.addPoint(57*xoffset-offset,47*xoffset-offset);
    p.addPoint(50*xoffset-offset,54*xoffset-offset);
    p.addPoint(40*xoffset-offset,54*xoffset-offset);
    p.addPoint(33*xoffset-offset,47*xoffset-offset);
    p.addPoint(33*xoffset-offset, 37*xoffset-offset);

    g.drawPolygon(p);
    g.dispose();

}

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (buffer != null) {
        Graphics2D g2d = (Graphics2D)g;
        g2d.drawImage(buffer, translateX, translateY, this);
    }
}

UPDATE

So, anyway, the other fun things you're doing are...

  1. Creating a static reference to your Polygon. Hope you weren't intending to have more the one on the screen at a time ;)
  2. Add new points to an already existing polygon (each time paintComponent was called)
  3. Translating the polygon each time paintComponent was called

Try something like this instead

public class RoundTop extends JPanel {

    //Polygons declarations
    private Polygon p = new Polygon();
    //Translate variables;
    private int translateX = 10;
    private int translateY = 10;

    public RoundTop() {

        int xoffset = 5;//Multiply in order to "zoom" the picture
        int offset = 0;//moves shape to the right

        p.addPoint(40 * xoffset - offset, 30 * xoffset - offset);
        p.addPoint(50 * xoffset - offset, 30 * xoffset - offset);
        p.addPoint(57 * xoffset - offset, 37 * xoffset - offset);
        p.addPoint(57 * xoffset - offset, 47 * xoffset - offset);
        p.addPoint(50 * xoffset - offset, 54 * xoffset - offset);
        p.addPoint(40 * xoffset - offset, 54 * xoffset - offset);
        p.addPoint(33 * xoffset - offset, 47 * xoffset - offset);
        p.addPoint(33 * xoffset - offset, 37 * xoffset - offset);

        p.translate(translateX, translateY);

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g.create();

        g2d.drawPolygon(p);

        g2d.dispose();

    }
}

Upvotes: 2

Related Questions