2016-11-21 38 views
0

我试图缩放图像以适合我GUI中的JPanel。每当我在JFrame中创建一个ImagePanel的新实例时,我会得到一个异常,因为宽度和高度均为0.但是,我忽略了getPreferredSize(),因此宽度和高度看起来应该是非零值。当为JPanel缩放图像时,宽度和高度必须为非零

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); 
} 
} 

这里是堆栈跟踪:

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) 
+0

你可以显示堆栈跟踪吗? – MordechayS

+0

@MordechayS是的,我刚刚添加了栈跟踪 – tpm900

+0

'getPreferredSize()'是一个请求,而不是一个保证。当你第一次创建'JPanel'时,它不是组件层次结构的一部分,所以它没有机会调整大小。在面板添加到父容器并进行布局后,您需要调用'scaleImage'。或者,您可以使用首选大小作为参数,而不是实际大小。 – resueman

回答

1

直到面板被显示在一个可见GUI的部件不具有大小。

因此,解决方案是在paintComponent(...)方法中动态缩放图像。

请注意,您可以直接使用drawImage(...)方法执行此操作。阅读API有一种方法,允许您在绘制图像时指定图像的宽度/高度。

0

Oracledocs

“的pack()方法尺寸帧,使得其所有内容均达到或 其优选尺寸以上...”

因此,直到您在包含JFrame的电话上拨打pack() - 您的组件将不会有任何大小,除了默认的大小 - 即

看到这些解答获得更多信息:

相关问题