java - 在 Java 中重新绘制 BufferedImage 不会更改面板的内容

标签 java swing bufferedimage

长话短说,我正在使用放入自定义 JPanel 中的 BufferedImage 绘制 Mandelbrot。我已经完成了集合的缩放,但在取消缩放时重新绘制时遇到问题。取消缩放时,我将图像的值更改为图像先前状态的值(我将每个状态保留在堆栈中)并重新绘制面板。问题是堆栈中的最后一个图像被弹出但没有绘制。

这些是我的实例变量

    private BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);  
    private Stack<BufferedImage> zooms = new Stack<BufferedImage>();  
    private boolean unzoom = false;  

这就是我缩放和推送要保存在堆栈上的图像的方式

public void mouseReleased(MouseEvent e)
{
    zooms.push(image);
    <some code for zooming that works>
    repaint();
}  

现在我想通过滚动来取消缩放

class WheelZoomListener implements MouseWheelListener
{
    public void mouseWheelMoved(MouseWheelEvent e) 
    {
        unzoom = true;  
    //this is how I assign the current image to be the one before the last zoom
        image = zooms.pop();
        repaint();
    }
}  

最后这是我的绘画方法

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    Graphics2D  g2d= (Graphics2D) g;  
     //if it is not unzooming draw the mandelbrot set normally by  
      //dealing with every pixel of the Buffered Image separately  
    if (!unzoom)
    {
        for(int i = 0; i < SIZE; i++)
        {
            for (int j = 0; j < SIZE; j++)
            {
                int iterations = getIterations(cnSet[i][j]);
                if (iterations == noIterations)
                {
                    color = Color.BLACK;
                }
                else
                {
                    color = cols[iterations%noIterations];
                }
                image.setRGB(i, j, color.getRGB());
            }
        }
    }  
//zooming or unzooming always draw the image in its current state
    g2d.drawImage(image, 0, 0, this);
    unzoom = false;
}  

修复:事实证明我不需要每次都保留最后一个图像并创建临时图像。相反,现在我只将复平面的坐标保留在堆栈中。这就是我需要重新绘制旧图像的全部内容。

最佳答案

这个:

private BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);

实例化一个新的 BufferedImage 并将该对象的引用存储在 image 中。

这个:

zooms.push(image);

将对您创建的单个 BufferedImage 的引用推送到堆栈上。

只要您继续使用相同的 BufferedImage,您所做的就是将对同一对象的多个引用推送到堆栈上;因此,对对象数据的更改会反射(reflect)在您放置在堆栈上的每个引用中,因为堆栈中的每个项目都指向同一个对象。

高级效果是每次渲染时都会将之前的每个状态更改为当前状态。

您需要为每个状态创建一个全新的BufferedImage;这样您粘贴在堆栈上的每个引用都指向一个唯一的对象。

看看这个 nice little article about how references work in Java .

关于java - 在 Java 中重新绘制 BufferedImage 不会更改面板的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22234780/

相关文章:

java - Java中的日期时间解析

java - 带有 base64 图像的 HTML 到 PDF 抛出 FileNotFoundException

java - 使 BoxLayout 将组件移动到顶部,同时从左到右堆叠

java - JFrame标题栏重叠图形

java - 将 BufferedImage 保存为 BMP/PNG/JPG,然后再打开

java - Spring:添加查询参数的惯用方式

java - 在 Talend 中 Access 编码 cp1250 的数据库

java - 自定义JButton样式

java - 如何从缓冲图像数组创建动画 gif?

java - 如何获取 bufferedImage 的缩放实例