长话短说,我正在使用我放在自定义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;
}
FIX:原来我不需要每次都保留最后一张图像和创建临时图像。相反,现在我只将复杂平面的坐标保存在堆栈中。这就是我重新绘制旧图像所需的全部内容。
这个:
private BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
实例化一个新的BufferedImage
并将对该对象的引用存储在image
中。
这个:
zooms.push(image);
将对您创建的单个BufferedImage
的引用推送到堆栈上。
只要您继续使用相同的BufferedImage
,您所做的就是将对同一对象的多个引用推送到堆栈上;因此,对对象数据的更改会反映在您放置在堆栈上的每个引用中,因为堆栈中的每个项目都指向同一个对象。
高级效果是每次渲染时都将以前的每个状态更改为当前状态。
您需要为每个状态创建一个全新的BufferedImage
;以便您粘贴在堆栈上的每个引用都指向一个唯一的对象。
看看这篇关于引用如何在Java中工作的好文章。