0

I'm trying to write a JPanel Picture to a BufferedImage (later converted to Rendered Image). I am getting a stack overflow error in the AWT-EventQueue-0 thread for some reason and am not sure if there is a reason I have overlooked.

The code in question:

public BufferedImage createImage() {
    int w = getWidth();
    int h = getHeight();
    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    cp.paint(bi.getGraphics());

    //debug script
    File outputfile = new File("image"+index+".jpg");
    try {
        ImageIO.write(bi, "jpg", outputfile);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    index++;


    return bi;
}

The JPanel paintComponent

@Override
protected void paintComponent(Graphics g) {

    super.paintComponent(g);
    r = new Random(System.nanoTime());
    int maxSize = 100;
    int randX = r.nextInt(getWidth());
    int randY = r.nextInt(getHeight());
    int randWidth = r.nextInt(maxSize);
    int randHeight = r.nextInt(maxSize);
    Color color = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
    Graphics2D g2d = (Graphics2D) g;

    ovals.add(new MyCircles(randX, randY, randWidth, randHeight, color));   
    for (MyCircles c : ovals) {
            c.paint(g2d);
    }
    g2d.setColor(getForeground());


    repaint();

    double current = ImageComparator.calcDistance((RenderedImage)createImage());

    //debugging script
    System.out.println("Current: " + current);
    System.out.println("Previous" + previous);


    if(current > previous) {
        ovals.remove(ovals.size()-1);
    }
    else {
        previous = current;
    }


}

Any insight as to how to amend this issue would be greatly appreciated!

2
  • 2
    Never call repaint() inside paintComponent() that's an infinite loop! Commented May 20, 2015 at 18:16
  • This solution uses the same createScreenShot method as my createImage. Thanks though. Commented May 20, 2015 at 18:48

3 Answers 3

4

Remove the the call to repaint in paintComponent which causes that method to be called ad infinitum

Sign up to request clarification or add additional context in comments.

5 Comments

This wasn't the problem. The error seems to reside in cp.paint(bi.getGraphics()); line for some reason
Any suggestions how to save my panel to a buffered image without calling paint in that case? The only other option I've found is writing it to a file which would be inefficient for my intentions.
@AdamWechter, calling paint() when painting onto a BufferedImage is fine. Fix your other problems first.
@AdamWechter It still seems like the repaint is the issue since paint calls the full paint stack including paintComponent
I've removed the repaint call and it resulted in the same problem. My problem is I am creating an infinite number of ovals one at a time trying to move slowly towards an existing saved picture (I use an image similarity evaluator) However in order to make this comparison, I need to have my panel in the form of a RenderedImage. My image comparer works, my program produces ovals randomly one at a time saving them to a list so that all are drawn in the next iteration of the picture (not just painting the newest oval) thus my problem revolves in that method somehow.
2

Not directly related to your problem but, you should never use the Random class in the painting method. Every time you call the method the painting will change, so the image you create and save will not be the same as the image on the panel.

Also, you should not be adding ovals in the paint method for the same reason give above.

You need to create an addOval(...) method that will set the random color of the Oval and add the oval to the List. The painting code will just iterate through the List and paint the Oval.

You also should NOT be removing ovals in the painting code. Painting code is for painting only, not manipulating the objects painted.

You can also try the Screen Image class which is basically a more flexible version of your image creation code.

2 Comments

My component painting method works as intended. Random only is used to add the new oval which is then saved to be later recalled from a list.
@AdamWechter, the code is wrong and you have a painting problem. Fix the code!
0

Of course you have infinite loop there:

here is how you call your methods:

createImage()
 |__paint()
    |__createImage() // again in ImageComparator.calcDistance line
       |__paint()
           |__createImage() // again in ImageComparator.calcDistance line
              |__paint()
                 |__createImage() // again in ImageComparator.calcDistance line
                   |__paint()
                        TOY STORY 1 (Buzz) : to the infinite and beyond it :)

You never stop this cycle.

I suggest that you need to get the images and then compare them outsize of your paint. Let the paint just paint the image and do the comparison outside of it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.