简体   繁体   中英

Width and Height must be non-zero when scaling image for JPanel

I am trying to scale an image to fit within a JPanel in my GUI. Whenever I create a new instance of ImagePanel in my JFrame, I get an exception because the width and the height are both 0. However, I overrode getPreferredSize() so it seems like the width and height should be non-zero values.

public class ImagePanel extends JPanel {

private Image image;

public ImagePanel() {
    try {
        image = ImageIO.read(new File("resources/opening.jpg"));
        image = scaleImage(image);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(image, 0, 0, this);
}

public void setImage(Image i) {
    image = scaleImage(i);
}

@Override
public Dimension getPreferredSize() {
    return new Dimension(500, 500);
}

public Image scaleImage(Image i) {
    return i.getScaledInstance(getWidth(), getHeight(), Image.SCALE_SMOOTH);
}
}

Here is the stack trace:

Exception in thread "main" java.lang.IllegalArgumentException: Width (0) and height (0) must be non-zero
at java.awt.image.ReplicateScaleFilter.<init>(ReplicateScaleFilter.java:102)
at java.awt.image.AreaAveragingScaleFilter.<init>(AreaAveragingScaleFilter.java:77)
at java.awt.Image.getScaledInstance(Image.java:172)
at ImagePanel.scaleImage(ImagePanel.java:40)
at ImagePanel.<init>(ImagePanel.java:18)
at GUIFrame.<init>(GUIFrame.java:44)
at main.main(main.java:6)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

A component doesn't have a size until the panel is displayed in a visible GUI.

So the solution is to do the scaling of your image dynamically in the paintComponent(...) method.

Note you can do this with the drawImage(...) method directly. Read the API there is a method that allows you to specify the width/height of the image as you paint the image.

From Oracle 's docs :

"The pack() method sizes the frame so that all its contents are at or above their preferred sizes ..."

So, until you call pack() on your containing JFrame - your components won't have any size except the default one - which is zero .

See these answers for more information:

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