/** * EtchedBorder is a simple border panel that is intended to enclose a * group of related user interface components. Based generally on Taligent's * BorderPanel and on sample code in Graphic Java.<p> * * Copyright &copy; 1996-1998 Martin Minow. All Rights Reserved.<p> * * Permission to use, copy, modify, and redistribute this software and its * documentation for personal, non-commercial use is hereby granted provided that * this copyright notice and appropriate documentation appears in all copies. This * software may not be distributed for fee or as part of commercial, "shareware," * and/or not-for-profit endevors including, but not limited to, CD-ROM collections, * online databases, and subscription services without specific license.<p> * * @author <a href="mailto:minow@apple.com">Martin Minow</a> * @version 1.0 * Set tabs every 4 characters. *//*************************************************************************** * Copyright and Permission Notice                                         * *                                                                         * * Permission is granted to copy, use, modify, and merge this software     * * into your applications and to permit others to do any of the foregoing  * * for non-commercial use only. You must include this permission and       * * copyright notice in all copies and modified versions of this software,  * * and include attribution to Taligent in all splash screens included in   * * any application using this software.                                    * *                                                                         * * THE SOFTWARE IS PROVIDED IN ITS 'AS IS' CONDITION FOR NON-COMMERCIAL    * * USE ONLY. TALIGENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR DAMAGES      * * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.                     * *                                                                         * * (C) Copyright Taligent, Inc. 1996,1997 All Rights Reserved.             * * (C) Copyright IBM Corporation 1996,1997                                 * ***************************************************************************/// package Classes;import java.awt.*;public class EtchedBorder extends Panel{	/**	 * EtchedBorder.LEFT, .CENTER, and .RIGHT align the label text.	 */	public static final int	LEFT					= 0;	public static final int	CENTER					= 1;	public static final int	RIGHT					= 2;	public static final Font	defaultLabelFont	= new Font("TimesRoman", Font.PLAIN, 12);	public static final Color	defaultLabelColor	= Color.black;	public static final int	defaultBorderThickness	= 4;	public static final int	defaultBorderGap		= 4;	private static final int	slop					= 5;	/* Surrounds text	*/	private Font			labelFont			= defaultLabelFont;	private String			labelText			= null;	private Color			labelColor			= defaultLabelColor;	private int				alignment			= LEFT;	private int				borderThickness		= defaultBorderThickness;	private int				borderGap			= defaultBorderGap;		/**	 * Constructor (no label)	 * @param insideComponent	What is displayed inside this Panel.	 */	public EtchedBorder(			Component		insideComponent		)	{		this(insideComponent, null);	}	/**	 * Create an EtchedBorder with the given label text.	 * @param insideComponent	What is displayed inside this Panel.	 * @param	labelText	The text to display.	 */	public EtchedBorder(			Component		insideComponent,			String			labelText		)	{		setLabelText(labelText);		setLayout(new BorderLayout());		add("Center", insideComponent);	}	/**	 * Return the panel insets.	 * @return	The panel insets.	 */	public Insets insets()	{		Insets insets				= super.insets();		int		borderThickness		= Math.max(1, this.borderThickness);		int		borderWidth			= borderThickness + borderGap;		int		topAdjustment		= borderWidth;		if (labelText != null && labelText.length() > 0) {			try {				FontMetrics fm		= getGraphics().getFontMetrics(labelFont);				int	ascent			= fm.getAscent();				int descent			= fm.getDescent();				int leading			= fm.getLeading();				int	height			= fm.getHeight();				if (height > borderThickness) {					topAdjustment	+= (height - borderThickness);				}				topAdjustment		+= (descent + leading);			}			catch (Exception e) { }	/* Ignore exception (no graphics context)	*/		}		if (topAdjustment < 2) {		/* Ensure room for the rectangle			*/			topAdjustment = 2;		}		if (borderWidth < 2) {			/* Ensure room for the rectangle			*/			borderWidth = 2;		}		insets.top		+= topAdjustment;		insets.left		+= borderWidth;		insets.right	+= borderWidth;		insets.bottom	+= borderWidth;		return (insets);	}	/**	 * Set the border thickness. This is the distance between the enclosure	 * and this panel.	 * @param	borderThickness	New thickness (minimum zero).	 * @return	This object (to simplify chaining initialization methods).	 */	public EtchedBorder setThickness(			int				borderThickness		)	{		if (borderThickness >= 0) {			layout();			repaint();		}		return (this);	}	/**	 * Set the border gap. This is the distance between this panel and	 * whatever it encloses.	 * @param	borderGap	New gap.	 * @return	This object (to simplify chaining initialization methods).	 */	public EtchedBorder setGap(			int				borderGap		)	{		if (borderGap >= 0) {			this.borderGap = borderGap;			layout();			repaint();		}		return (this);	}	/**	 * Set the label text font.	 * @param	labelFont	new label font	 * @return	This object (to simplify chaining initialization methods).	 */	public EtchedBorder setLabelFont(			Font			labelFont		)	{		if (labelFont != null) {			this.labelFont = labelFont;			layout();			repaint();		}		return (this);	}	/**	 * Set the label text string.	 * @param	labelText	new text	 * @return	This object (to simplify chaining initialization methods).	 */	public EtchedBorder setLabelText(			String			labelText		)	{		this.labelText = labelText;		layout();		repaint();		return (this);	}	/**	 * Set the label alignment.	 * @param	alignment	new alignment	 * @return	This object (to simplify chaining initialization methods).	 */	public EtchedBorder setAlignment(			int				alignment		)	{		this.alignment = alignment;		layout();		repaint();		return (this);	}	/**	 * Set the label text color.	 * @param	labelColor	new label text color	 * @return	This object (to simplify chaining initialization methods).	 */	public EtchedBorder setLabelColor(			Color			labelColor		)	{		this.labelColor		= labelColor;		repaint();		return (this);	}	/**	 * Paint the border and draw the text.	 */	public void paint(			Graphics	g		)	{		Dimension	d					= size();		int			width				= d.width;		int			height				= d.height;		g.setFont(labelFont);		FontMetrics	fm					= g.getFontMetrics();		int			ascent				= fm.getAscent();		int			adjustment			= 0;		int			borderThickness		= Math.max(1, this.borderThickness);		if (labelText != null && labelText.length() > 0) {			if (ascent > borderThickness) {				adjustment = (ascent - borderThickness) / 2;			}		}		int		x						= borderThickness / 2;		int		y						= x + adjustment;		int		w						= width - borderThickness - 1;		int		h						= height - borderThickness - 1 - adjustment;		g.setColor(getBackground().brighter().brighter().brighter());		g.drawRect(x + 1, y + 1, w, h);		g.setColor(getBackground().darker().darker().darker());		g.drawRect(x, y, w, h);		if (labelText != null && labelText.length() > 0) {			int		thickness			= borderThickness + slop;			int		fontHeight			= fm.getHeight();			int		labelWidth			= fm.stringWidth(labelText);			int		textWidth			= width - (thickness * 2);			if (labelWidth > textWidth) {				labelWidth				= textWidth;			}			int		offset;			switch (alignment) {			case CENTER:	offset = (width - labelWidth) / 2;				break;			case RIGHT:		offset = (width - labelWidth - thickness);	break;			default:			case LEFT:		offset = thickness;							break;			}			g.clearRect(offset - slop, 0, labelWidth + slop * 2, fontHeight);			g.clipRect(offset, 0, labelWidth, fontHeight);			g.setColor(labelColor);			g.drawString(labelText, offset, ascent);			g.clipRect(0, 0, width, height);		}	}}