Showing old BufferedImage after rotate. Why?

After I rotate a BufferedImage, I still see the old one.

I can flip (vertical, and horizontal) an image but when I try to scale or rotate it, the old image is still showing up. I’ve tried every repaint, remove, removeall, etc that I can think of but still have double vision! :o

Note that if I resize the window large enough ( just a little movement won’t do it) then the old image does go away!

Here is the code that I use to rotate a loaded BufferedImage:

public static BufferedImage rotateImage(BufferedImage bi)
{
BufferedImage new_bi = new BufferedImage( bi.getHeight(),
bi.getWidth(),
bi.getType());

Graphics2D g2d = new_bi.createGraphics();
AffineTransform at = g2d.getTransform();
AffineTransform rotation = new AffineTransform();
rotation.rotate(Math.PI / 2, bi.getWidth() / 2, bi.getHeight() / 2);

g2d.transform(rotation);

g2d.drawImage( bi,
null,
bi.getWidth() / 2 - new_bi.getWidth() / 2,
(bi.getHeight() / 2 - new_bi.getHeight() / 2) * -1);

g2d.setTransform(at);

return new_bi;
}

The code that displays the new BufferedImage that is returned from the rotateImage method looks like this

private void displayBufferedImage(BufferedImage bif)
{
jpMainPanel = new JPanel();
jpMainPanel.setLayout(new BorderLayout());
jpMainPanel.setOpaque(false);
setTitle(“Display Program”);

if(jlBackground != null)
{
//This doesn’t help…but I tried it
getLayeredPane().remove(jlBackground);
getLayeredPane().repaint();

this.getContentPane().removeAll();
this.repaint();
}

jlBackground = new JLabel();

ImageIcon backImage = new ImageIcon(bif);

jlBackground.setIcon(backImage);
jlBackground.setBounds(0, 0, backImage.getIconWidth(), backImage.getIconHeight());
getLayeredPane().add(jlBackground, new Integer(Integer.MIN_VALUE));

setContentPane(jpMainPanel);

//Tried all of the following too…no help
jlBackground.repaint();
getLayeredPane().repaint();
jpMainPanel.repaint();
this.repaint();
this.getContentPane().repaint();
}

I think if I can get the Rotate to work, then the scale will follow the same principle.

Can anyone help me cure my double vision please?

well, your rotation code works fine, so it must be that you’re not using the updated image or something - probably a simple logic bug somewhere.

Also, you seem to be modifying swing components from a thread other than EventDispatchThread, which is a big no-no.

All you need to do is to set a new image to that JLabel, there’s no need to remove/add it, and call all those repaint methods.

Thanks for the reply, but it brings up a quesiton:

Given that the application is single threaded, do you still think that invokeLater or invokeAndWait are needed to update the swing components?

with swing – yes. your code may only involve one thread, but there are plenty more running in the periphory (sp?)

That isn’t the way I understood it. I was always under the impression that you were safe in a single threaded application, and have never read anything that mentions the use of invokeAndWait or invokeLater outside the context of a multi-threaded application.

Yes, there are multiple threads being run in a single threaded app, but these, it is my understanding, do not mess with the EventDispatch thread to cause it problems.

Thanks for setting me straight!

Still, can someone point me to some documentation (I looked on the Net, but couldn’t find any) that says that all references to a Swing component to do things like show() must be done using invokeAndWait or invokeLater for a single threaded application? I’d like to read it for myself to understand what is going on to require this in a single threaded application.

Thanks.

BTW, I’ve never had a problem with this, but then again I normally use multi-threaded apps too!

http://java.sun.com/docs/books/tutorial/uiswing/mini/threads.html

Thanks.

I read that one years ago but I assumed at the time that it applied to multi-threaded apps since it was titled “Threads and Swing”.