You want to draw text or graphical objects with a “drop shadow” effect, as in Figure 12-3.
Draw the component twice, with the darker shadow behind and the “real” color, slightly offset, in front.
Program DropShadow
does just this. It also uses a
Font
object from java.awt
to
exercise some control over the typeface.
The program in Example 12-1 is unabashedly an Applet; to run it, you should invoke it as appletviewer DropShadow.htm [28] (the details of such HTML files are in Section 17.2).
Example 12-1. DropShadow.java
import java.applet.*; import java.awt.*; /** * DropShadow -- show overlapped painting. */ public class DropShadow extends Applet { /** The label that is to appear in the window */ protected String theLabel = null; /** The width and height */ protected int width, height; /** The name of the font */ protected String fontName; /** The font */ protected Font theFont; /** The size of the font */ protected int fontSize = 18; /** The offset for the drop shadow */ protected int theOffset = 3; /** True if we got all required parameters */ protected boolean inittedOK = false; /** Called from the browser to set up. We want to throw various * kinds of exceptions but the API predefines that we don't, so we * limit ourselves to the ubiquitous IllegalArgumentException. */ public void init( ) { // System.out.println("In DropShadow init( )"); theLabel = getParameter("label"); if (theLabel == null) throw new IllegalArgumentException("LABEL is REQUIRED"); // Now handle font stuff. fontName = getParameter("fontname"); if (fontName == null) throw new IllegalArgumentException("FONTNAME is REQUIRED"); String s; if ((s = getParameter("fontsize")) != null) fontSize = Integer.parseInt(s); if (fontName != null || fontSize != 0) { theFont = new Font(fontName, Font.BOLD + Font.ITALIC, fontSize); System.out.println("Name " + fontName + ", font " + theFont); } if ((s = getParameter("offset")) != null) theOffset = Integer.parseInt(s); setBackground(Color.green); inittedOK = true; } /** Paint method showing drop shadow effect */ public void paint(Graphics g) { if (!inittedOK) return; g.setFont(theFont); g.setColor(Color.black); g.drawString(theLabel, theOffset+30, theOffset+50); g.setColor(Color.white); g.drawString(theLabel, 30, 50); } /** Give Parameter info to the AppletViewer, just for those * writing HTML without hardcopy documentation :-) */ public String[][] getParameterInfo( ) { String info[][] = { { "label", "string", "Text to display" }, { "fontname", "name", "Font to display it in" }, { "fontsize", "10-30?", "Size to display it at" }, }; return info; } }
Standard
AWT uses a very simple paint model
for drawing. I guess that’s why the method you have to write is
called paint( )
. Let’s go back to the paper
age for a moment. If you paint something on a piece of paper and then
paint over it with a different color, what happens? If you’re
old enough to remember paper, you’ll know that the second color
covers up the first color. Well, AWT works in pretty much the same
way. No fair asking about water-based paints that run together;
Java’s painting is more like fast-drying oil paints. The
fact that AWT retains all the bits
(pixels, or picture elements) that you don’t draw, plus the
fact that methods like drawString( )
have
extremely good aim, make it very easy to create a drop shadow and to
combine graphics drawings in interesting ways.
Remember to draw from the back to the front, though. To see why, try
interchanging the two calls to drawString( )
in
the previous code.
A word of warning: don’t mix drawing with added
GUI components (see Chapter 13). For example, say you had a paint method in
an applet or other container and had add( )
ed a
button to it. This works on some implementations of Java, but not on
others: only the painting or the button will appear, not both.
It’s not portable, so don’t do it -- you’ve been
warned! Instead, you should probably use multiple components; see the
JFrame
’s getContentPane( )
and getGlassPane( )
, discussed in
Chapter 8 of Java Swing, for details.
An alternative method of obtaining a drop shadow effect is covered Section 12.10.
[28] In all my applet examples I
use a filename ending in
htm
instead of the more traditional
html
, because the Javadoc program (see Section 23.3) will overwrite the html
file without notice. AppletViewer
doesn’t care either way.
18.223.206.225