Image panel not repainted unless on system events
A friend of mine asked me to help him with Swing, and I reached a point where I can't solve an issue. So, first I have an ImagePanel
public class ImagePanel extends JPanel {
private Image img;
public void setImage(String img) {
setImage(new ImageIcon(img).getImage());
}
public void s开发者_StackOverflow社区etImage(Image img) {
int width = this.getWidth();
int height = (int) (((double) img.getHeight(null) / img.getWidth(null)) * width);
this.img = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
}
@Override
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}
And a FileChooser
, which should open the selected image into the ImagePanel. It simply calls setImage
of the ImagePanel
. But the image is not painted. No combinations of repatint, validate and invalidate help.
However, the image is painted when the JFrame
is resized (using the mouse).
So, the question is - what method is called on resizing (using the mouse), which makes the ImagePanel
to be repainted successfully.
IconImage is using MediaTracker to load the image asynchronously. At the point where you're calling repaint, invalidate, etc, the image has not finished loading.
In your paintComponent, replace
g.drawImage(img, 0, 0, null);
with
g.drawImage(img, 0, 0, this);
The Component class has an implementation of ImageObserver that will call repaint when the image has finished loading.
Setting the image and painting it as you are in your code doesn't change the actual size of the component. Depending on the layout and setup of the containing frame, a few different things may be happening - your ImagePanel may be initially of size 0x0, and so doesn't display until you enlarge the frame and more space is allocated to the ImagePanel; or the ImagePanel is manually sized to a large size that doesn't fit within the starting size of the JFrame, in this case the ImagePanel may not be displayed until enough size is available after resizing.
Calling the repaint method (documentation link) will cause the panel to be repainted. This leads to an underlying call to paint, which is what is also causing the JPanel to paint when you resize it.
精彩评论