• Post Reply Bookmark Topic Watch Topic
  • New Topic

JPanel refresh after updating BufferedImage

 
Yui Park
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello. I would like to get some advice please.

I'm currently trying to display pictures, jpg/jpeg/png/gif/tiff on a JPanel. (JFrame - JPanel - BufferedImage loaded by JButton, ActionListener and JFileChooser)

I achieved most parts, but my JPanel doesn't refresh promptly. Once I load a picture, BufferedImage, it shows nicely. However, if I load another picture from the second time, it shows simply on top of the previous image. If I resize my frame or move to edge and bring it back, the old image is cleared from my panel, leaving only the new image.

My JFileChoose calls "myPanel.repaint()" to refresh it every time I load another image. My overwritten paint() method has g.drawImage(img, 0, 0, null) only.

I thought what I am trying to do is simple enough for many people here, so I did not attach my messy code. If helps, I will post it.

If I could get any advice, it would be very appreciated.

Sincerely,
Yui
 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My overwritten paint() method has g.drawImage(img, 0, 0, null) only.


There is no need to do custom painting for this. Just use a JLabel and add in ImageIcon to the label. Whenever you change the image you just do label.setIcon(...).

However, if you do use custom painting, then you should be overriding the paintComponent() method, NOT paint(). YOu would also need code to calculate the preferred size of your component and you would need to invoke revalidate() and repaint() on the component. Thats why a JLabel is easier. It already does all this for you.
 
Yui Park
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob, thank you very much for your comments/reply.

I haven't yet tried changing my code, but I have a few questions.

1. When would you use Image/BufferedImage instead of ImageIcon ?
2. When would you use JPanel instead of JLabel ?

I've been reading Java Doc, but I haven't yet established solid foundation yet...
 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
1. When would you use Image/BufferedImage instead of ImageIcon ?


If you want to do custom painting with the image. For example, maybe you want to "scale" the image to fill the entire window. A JLabel always paints the image at its actual size.

2. When would you use JPanel instead of JLabel ?


When you want to do custom painting.

 
Yui Park
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you very much Rob. I'll take a note. Time to practice !

Sincerely,
Yui
 
Yui Park
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For anyone who might have similar issue:

I added revalidate() method on my panel and it already resolved my issue of myPanel not refreshing properly.

Also, paintComponent() should be called instead of paint(). paintComponent() will only paint the component which update the Graphics, not the entire Top Level container. (More efficient)

Yui
 
Darryl Burke
Bartender
Posts: 5155
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No. The revalidate() method is required to be invoked after adding/removing components to/from an already visible Container.

Your paintComponent(...) override should call the super implementation to clear the background.
 
Darryl Burke
Bartender
Posts: 5155
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yui Park wrote:paintComponent() will only paint the component which update the Graphics, not the entire Top Level container. (More efficient)


Both paint only the component on which the method was invoked. The API is very clear on the difference between the two methods.
 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The revalidate() method is required to be invoked after adding/removing components to/from an already visible Container.


That is a common usage but I believe it is more general than that. I believe is should be used when the size of the component changes.

In the case of a JPanel being used as a container, adding/removing components will obviously affect its size so revalidate() needs to be used.

However in other components, changing a property of the component can also change its size. Check out the source code for JLabel and the setIcon() and setText() methods for example. The revalidate() method is invoked when there is a potential size change. Actually most setter methods invoke revalidate()/repaint() just to be safe I guess. So I guess if you really want to generalize you should always invoke those methods.
 
Yui Park
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually, super.paintComponent(g) works better.

When I added revalidate() method to my code, it worked after I resized my window once after program's launch. (It didn't refresh if I didn't resize.) However, when I removed revalidate() and added super.paintComponent(g) to my override paintComponent(g), it is currently working like a charm

Also, thank you for correction on my wrong comments about paint(g) vs paintComponent(g).

Is there any documentation I could read about paint(g) vs paintComponent(g)?
 
Rob Camick
Ranch Hand
Posts: 2699
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is there any documentation I could read about paint(g) vs paintComponent(g)?


See Custom Painting
 
Yui Park
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is a great tutorial. I don't know why I missed this during search.

Thank you very much !
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!