PictureBorder – A nice Border with images!

This is a very useful extension of the AbstractBorder class I made, and it’s excellent for use with pretty GUI’s. Swing’s included Border’s are not really very pretty, remaining colorless and dull. If you want a professional-looking and fun interface, this is a great class to use in your Java app. It lets you use images loaded from your computer as the borders around any component, instead of a line or some text like in Swing’s included Borders. For more details on the abilities of this class, read the comments in the class. The code is not complicated at all, most people should be able to understand it regardless of experience. [EDIT] I forgot the imports, oops.[/EDIT]

For an example of the possible prettiness, take a look at this screenshot of what I originally made this class for:

http://www.spearandassociates.com/images/extra/ACConnector.jpg


import javax.swing.border.AbstractBorder;
import javax.swing.ImageIcon;
import java.awt.Insets;

/**
 * PictureBorder is an extension of AbstractBorder that is used to draw images
 * into the insets around a component in a GUI. The images are automatically
 * resized as needed, and you have the ability of using one single image
 * four times or four separate images. Feel free to add or remove anything
 * if you feel it might help you on your project.
 * @author Eli Delventhal, useable by anyone for free, please just credit me
 */
public class PictureBorder extends AbstractBorder
{
	//Each ImageIcon represents a different Image's direction
	private ImageIcon north;
	private ImageIcon south;
	private ImageIcon east;
	private ImageIcon west;
	//The insets control how large the images are when drawn
	private Insets insets = new Insets(25,25,25,25);
	//If topBottom is true, the top and bottom are drawn last,
	//taking up some space of the left and right sides.
	//In the opposite case, they are drawn first.
	private boolean topBottom = true;
	//If constrain is true, the insets are maintained unless
	//manually changed. If it is false, the insets are resized
	//to fit the original image sizes, so they are not warped
	private boolean constrained;
	
	/**
	 * This constructor displays the same image, of location str,
	 * four times around the component. The insets are resized
	 * by default to maintain the same image proportions.
	 * @param str The location on the HD of the image
	 */
	public PictureBorder(String str)
	{
		north = south = east = west = new ImageIcon(str);
		constrained = false;
	}
	
	/**
	 * This constructor displays the same image, of location str,
	 * four times around the component. The images are skewed to
	 * fit the supplied insets, regardless of window or image size.
	 * @param s The location on the HD of the image
	 * @param i The insets (border sizes) for the images
	 */
	public PictureBorder(String s, Insets i)
	{
		north = south = east = west = new ImageIcon(s);
		insets = i;
		constrained = true;
	}
	
	/**
	 * This constructor displays four separate images around the
	 * component. The insets are resized by default to maintain
	 * the same image proportions.
	 * @param n The location on the HD of the northern image
	 * @param s The location on the HD of the southern image
	 * @param e The location on the HD of the eastern image
	 * @param w The location on the HD of the western image
	 */
	public PictureBorder(String n, String s, String e, String w)
	{
		north = new ImageIcon(n);
		south = new ImageIcon(s);
		east = new ImageIcon(e);
		west = new ImageIcon(w);
		constrained = false;
	}
	
	/**
	 * This constructor displays four separate images around the
	 * component. The images are skewed to fit the supplied
	 * insets, regardless of window or image size.
	 * @param n The location on the HD of the northern image
	 * @param s The location on the HD of the southern image
	 * @param e The location on the HD of the eastern image
	 * @param w The location on the HD of the western image
	 * @param i The insets (border sizes) for the images
	 */
	public PictureBorder(String n, String s, String e, String w, Insets i)
	{
		north = new ImageIcon(n);
		south = new ImageIcon(s);
		east = new ImageIcon(e);
		west = new ImageIcon(w);
		insets = i;
		constrained = true;
	}
	
	/**
	 * If true, then the top and bottom banners will be drawn on last.
	 * If false, they will be overlapped by the east and west banners.
	 * @param b T/F top and bottom are drawn last.
	 */
	public void setDrawTopBottomLast(boolean b)
	{
		topBottom = b;
	}
	
	/**
	 * If constrain is true, the insets are maintained unless
	 * manually changed. If it is false, the insets are resized
	 * to fit the original image sizes, so they are not warped
	 * @param b T/F the insets are constrained upon creation
	 */
	public void setConstrained(boolean b)
	{
		constrained = b;
	}
	
	/**
	 * @return true if top and bottom drawn last (in front), false otherwise
	 */
	public boolean drawsTopBottomLast()
	{
		return topBottom;
	}
	
	/**
	 * @return true if the insets are constrained on creation, false otherwise
	 */
	public boolean isConstrained()
	{
		return constrained;
	}
	
	/**
	 * Paints the border for the component. You will never have to call this method,
	 * it is used by swing to draw the borders as needed.
	 */
	public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
	{
		//Draw the top and bottom on top
		if (topBottom)
		{
			int hi = insets.top + insets.bottom;
			if (!constrained)
			{
				//We use the stretch ratios to determine exactly how much we're shaving off in the end
				insets.top = (int) ((width+0.0)/north.getIconWidth() * north.getIconHeight());
				insets.bottom = (int) ((width+0.0)/south.getIconWidth() * south.getIconHeight());
				hi = insets.top + insets.bottom;
				insets.right = (int) ((height+0.0-hi)/east.getIconHeight() * east.getIconWidth());
				insets.left = (int) ((height+0.0-hi)/west.getIconHeight() * west.getIconWidth());
			}
			//Actually draw the images with the correct dimensions now
			g.drawImage(east.getImage(),x+width-insets.right,y+insets.top,insets.right,height-hi,east.getImageObserver());
			g.drawImage(west.getImage(),x,y+insets.top,insets.left,height-hi,west.getImageObserver());
			g.drawImage(north.getImage(),x,y,width,insets.top,north.getImageObserver());
			g.drawImage(south.getImage(),x,y+height-insets.bottom,width,insets.bottom,south.getImageObserver());
		}
		//Draw the left and right on top
		else
		{
			int wi = insets.left + insets.right;
			if (!constrained)
			{
				//We use the stretch ratios to determine exactly how much we're shaving off in the end
				insets.right = (int) ((height+0.0)/east.getIconHeight() * east.getIconWidth());
				insets.left = (int) ((height+0.0)/west.getIconHeight() * west.getIconWidth());
				wi = insets.left + insets.right;
				insets.top = (int) ((width+0.0-wi)/north.getIconWidth() * north.getIconHeight());
				insets.bottom = (int) ((width+0.0-wi)/south.getIconWidth() * south.getIconHeight());
			}
			//Actually draw the images with the correct dimensions now
			g.drawImage(north.getImage(),x+insets.left,y,width-wi,insets.top,north.getImageObserver());
			g.drawImage(south.getImage(),x+insets.left,y+height-insets.bottom,width-wi,insets.bottom,south.getImageObserver());
			g.drawImage(east.getImage(),x+width-insets.right,y,insets.right,height,east.getImageObserver());
			g.drawImage(west.getImage(),x,y,insets.left,height,west.getImageObserver());
		}
	}
	
	/**
	 * Simply returns the insets of the image, used by Swing
	 * to determine how much of the component to cut off. You
	 * will never have to call this method.
	 */
	public Insets getBorderInsets(Component c)
	{
		return insets;
	}
}

Wow, thats really nice! Thanks :slight_smile:

Kev

Thanks a lot. I’m glad you didn’t tell me this existed already as a library function, because I was shocked when I found it wasn’t. :slight_smile: