简体   繁体   中英

Repainting a BufferedImage in Java does not change contents of panel

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM