tags:

views:

67

answers:

3

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 setImage(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.

A: 

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.

gab
and when I manually call repaint, to either or both the JFrame and the Image panel, nothing happens.
Bozho
Are you repeatedly calling setImage along with the resize, or is setImage only called once and then the window is resized? Maybe you could post some more of your code.
gab
+3  A: 

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.

Devon_C_Miller
+1  A: 

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.

Nate
Thanks. There was initially the resizing code, but I removed it in my attempts. Now, combined with Davon's answer, it works. I wish I had two green ticks :)
Bozho