Posted by Darryl Burke on March 31, 2012
An implementation of the Icon interface reports its size via the two methods getIconWidth() and getIconHeight(). It’s normal to expect that the Icon’s paintIcon(Component, Graphics, int, int) method will respect these bounds. If I had designed Swing’s interaction with Icons, I would have made sure of that by setting a clip to the Graphics passed to paintIcon(…).
Luckily for me, I didn’t design Swing, as that would have made StretchIcon impossible.
StretchIcon is an Icon that scales its image to fill the component area, excluding any border or insets, optionally maintaining the image’s aspect ratio by padding and centering the scaled image horizontally or vertically. Since the component now determines the size of the Icon, rather than the other way round, StretchIcon can be used only in conjunction with a component whose size is determined by the size and layout of the container it is placed in; for example, a JLabel placed in the BorderLayout.CENTER of a JFrame.
Using a StretchIcon is a viable alternative to extending a JComponent or JPanel solely to paint a custom background. The class can also improve the aesthetics of JLabels or JButtons in a resizable GridLayout, as in a game board. For both use cases, the image chosen should be of a size equal or near the maximum anticipated size of the component, since drawing an image larger than its natural size can lead to pixelation.
StretchIcon is a drop-in replacement for ImageIcon, which it extends, except that ImageIcon’s no-arg constructor isn’t supported. That’s because I feel that an ImageIcon without an Image is an oxymoron.