Java 将Jpanel写入缓冲映像堆栈溢出

Java 将Jpanel写入缓冲映像堆栈溢出,java,swing,bufferedimage,Java,Swing,Bufferedimage,我正在尝试将JPanel图片写入BuffereImage(稍后转换为渲染图像)。出于某种原因,我在AWT-EventQueue-0线程中遇到堆栈溢出错误,不确定是否有我忽略的原因 有关守则: public BufferedImage createImage() { int w = getWidth(); int h = getHeight(); BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_IN

我正在尝试将JPanel图片写入BuffereImage(稍后转换为渲染图像)。出于某种原因,我在AWT-EventQueue-0线程中遇到堆栈溢出错误,不确定是否有我忽略的原因

有关守则:

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;
}
JPanel组件

@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;
    }


}

任何关于如何修改此问题的见解都将不胜感激

删除
paintComponent
中对
repaint
的调用,该调用导致该方法被无限调用删除
paintComponent
中对
repaint
的调用,该调用导致该方法被无限调用与您的问题没有直接关系,但是,在绘制方法中不应使用Random类。每次调用该方法时,绘图都会更改,因此创建和保存的图像将与面板上的图像不同

此外,您不应该在绘制方法中添加椭圆,原因与上面给出的相同

您需要创建一个
addOval(…)
方法,该方法将设置椭圆的随机颜色并将椭圆添加到列表中。绘制代码将在列表中迭代并绘制椭圆形

您也不应该在绘制代码中删除椭圆。绘制代码仅用于绘制,而不是操纵绘制的对象


您也可以尝试使用该类,它基本上是图像创建代码的一个更灵活的版本。

与您的问题没有直接关系,但是,您不应该在绘制方法中使用Random类。每次调用该方法时,绘图都会更改,因此创建和保存的图像将与面板上的图像不同

此外,您不应该在绘制方法中添加椭圆,原因与上面给出的相同

您需要创建一个
addOval(…)
方法,该方法将设置椭圆的随机颜色并将椭圆添加到列表中。绘制代码将在列表中迭代并绘制椭圆形

您也不应该在绘制代码中删除椭圆。绘制代码仅用于绘制,而不是操纵绘制的对象


您也可以尝试该类,它基本上是图像创建代码的更灵活版本。

当然,您有无限循环:

以下是您如何调用方法:

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 :)
你永远不会停止这个循环


我建议你需要得到这些图像,然后将它们与你的画作进行比较。让画作只画图像,并在图像外部进行比较。

当然,这里有无限循环:

以下是您如何调用方法:

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 :)
你永远不会停止这个循环


我建议你需要得到这些图像,然后将它们与你的画作进行比较。让绘制只绘制图像并在图像外部进行比较。

不要在paintComponent()内部调用repaint(),这是一个无限循环!此解决方案使用与我的createImage相同的createScreenShot方法。谢谢。千万不要在paintComponent()内部调用repaint(),这是一个无限循环!此解决方案使用与我的createImage相同的createScreenShot方法。谢谢,这不是问题所在。错误似乎存在于cp.paint(bi.getGraphics())中;出于某些原因,有没有建议如何在不调用paint的情况下将面板保存到缓冲图像?我发现唯一的另一种选择是将其写入一个文件,这对我的意图来说是低效的。@AdamWechter,在对BuffereImage进行绘制时调用paint()就可以了。首先修复您的其他问题。@AdamWechter由于
paint
调用了包括
paintComponent
在内的完整绘制堆栈,因此重新绘制似乎仍然是问题所在,我已删除了重新绘制调用,并导致了相同的问题。我的问题是,我一次创建一个无限多的椭圆形,试图缓慢地向现有保存的图片移动(我使用图像相似性计算器),但是为了进行比较,我需要以渲染图像的形式创建面板。我的图像比较器工作正常,我的程序一次随机生成一个椭圆形,并将它们保存到列表中,以便在下一次迭代的图片中绘制所有的椭圆形(不仅仅是绘制最新的椭圆形),因此我的问题以某种方式在该方法中旋转。这不是问题所在。错误似乎存在于cp.paint(bi.getGraphics())中;出于某些原因,有没有建议如何在不调用paint的情况下将面板保存到缓冲图像?我发现唯一的另一种选择是将其写入一个文件,这对我的意图来说是低效的。@AdamWechter,在对BuffereImage进行绘制时调用paint()就可以了。首先修复您的其他问题。@AdamWechter由于
paint
调用了包括
paintComponent
在内的完整绘制堆栈,因此重新绘制似乎仍然是问题所在,我已删除了重新绘制调用,并导致了相同的问题。我的问题是,我一次创建一个无限多的椭圆形,试图缓慢地向现有保存的图片移动(我使用图像相似性计算器),但是为了进行比较,我需要以渲染图像的形式创建面板。我的图像比较器工作,我的程序一次随机生成一个椭圆形,并将它们保存到列表中,以便在下一次迭代中绘制所有的图片(不仅仅是绘制最新的椭圆形),因此我的问题以某种方式在该方法中旋转。我的组件绘制方法按预期工作。“仅随机”用于添加新的椭圆形,然后保存该椭圆形,以便以后从列表中调用。@AdamWechter,代码错误,您有绘画问题。修正代码!我的组件绘制方法按预期工作。“仅随机”用于添加新的椭圆形,然后保存该椭圆形,以便以后从列表中调用。@AdamWechter,代码错误,您有绘画问题。修正代码!