14
|
Chapter 1, Basic JComponents
#3 Fill Your Borders with Pretty Pictures
HACK
H A C K
#3
Fill Your Borders with Pretty Pictures
Hack #3
Swing comes with a set of customizable borders, but sometimes you want
more than they provide. This hack shows how to create a completely image-
based border that can be resized.
Swing has a prefabricated border, called the MatteBorder, which can accept
an image in its constructor. For simple tiled backgrounds, such as a checker-
board pattern, this works fine. However, if you want to have particular
images in each corner, creating a fully resizable image border, then you’ll
need something more powerful. Fortunately, Swing makes it very easy to
create custom border classes. The image border in this hack will produce a
border that looks like Figure 1-12.
The first step to any custom border is to subclass
AbstractBorder and imple-
ment the
paintBorder( ) method. The class will take eight images in the con-
structor, one for each corner and each side; all the code is shown in
Example 1-6.
Figure 1-12. An image-based border
Example 1-6. Building an image-based border
public class ImageBorder extends AbstractBorder {
Image top_center, top_left, top_right;
Image left_center, right_center;
Image bottom_center, bottom_left, bottom_right;
Insets insets;
public ImageBorder(Image top_left, Image top_center, Image top_right,
Image left_center, Image right_center,
Image bottom_left, Image bottom_center, Image bottom_right) {
this.top_left = top_left;
this.top_center = top_center;
this.top_right = top_right;
this.left_center = left_center;
this.right_center = right_center;
this.bottom_left = bottom_left;
this.bottom_center = bottom_center;
this.bottom_right = bottom_right;
}
Fill Your Borders with Pretty Pictures #3
Chapter 1, Basic JComponents
|
15
HACK
The two methods after the constructor control the border insets. These are
the gaps between the panel’s outer edge (and its parent) and the inner edge
of the panel where the panel’s children are drawn.
setInsets( ) lets you set
any size insets, but most of the time you want the insets to be based on the
actual images that make up the border. The implementation of
getBorderInsets( ) returns the insets variable if it’s not null. However, if the
developer didn’t set the insets, then they will be derived from the widths and
heights of the images that make up each side of the border (top, bottom,
left, and right).
To actually draw the border, align the corner images to the appropriate cor-
ners and then tile the side images along each border side. Doing this will
require using the
TexturePaint class, which is an implementation of the
Paint interface. Unfortunately, TexturePaint takes only BufferedImages, not
regular ones, so you’ve got to convert your images before use.
BufferedImages are a special form of image that the Java2D framework can
read and write at a pixel level. The standard
Image is controlled by the oper-
ating system and is very difficult to access at the pixel level. Java doesn’t let
you do a straight conversion between the two kinds of images, but you can
just draw one image on top of another, which is what this method in the
ImageBorder class does:
public BufferedImage createBufferedImage(Image img) {
BufferedImage buff = new BufferedImage(img.getWidth(null),
img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics gfx = buff.createGraphics( );
gfx.drawImage(img, 0, 0, null);
gfx.dispose( );
return buff;
}
public void setInsets(Insets insets) {
this.insets = insets;
}
public Insets getBorderInsets(Component c) {
if(insets != null) {
return insets;
} else {
return new Insets(top_center.getHeight(null),
left_center.getWidth(null),
bottom_center.getHeight(null), right_center.getWidth(null));
}
}
Example 1-6. Building an image-based border (continued)

Get Swing Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.