Question

Long story short I am drawing the Mandelbrot using a BufferedImage that I put in a custom JPanel. I have already done the zooming in the set but have problems with repainting when unzooming. When unzooming I change the value of the image to that of the previous state of the image(I keep every state in a Stack) and repaint the panel. Problem is that the last image in the stack gets popped off but it is not drawn.

These are my instance variables

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

This is how I zoom and push the image that I want to save on a stack

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

Now I want to unzoom by scrolling

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();
    }
}  

Finally this is my paint method

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: It turned out that I don't need to keep the last image and create temporary images every time. Instead now I only keep the coordinates of the complex plane in a stack. That is all I need to repaint the old image again.

Was it helpful?

Solution

This:

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

Instantiates a new BufferedImage and stores a reference to that object in image.

This:

zooms.push(image);

Pushes the reference to that single BufferedImage you created onto the stack.

As long as you keep using the same BufferedImage, all you are doing is pushing multiple references to the same object onto the stack; so changes to the object's data are reflected in every reference you've placed on the stack, because every item in the stack points to the same object.

The high-level effect is you are changing every previous state to the current one every time you render.

You'll want to create a whole new BufferedImage for each state; so that each reference you stick on the stack points to a unique object.

Take a look at this nice little article about how references work in Java.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top