Drawing a Drop Shadow

Problem

You want to draw text or graphical objects with a “drop shadow” effect, as in Figure 12-3.

Drop shadow text

Figure 12-3. Drop shadow text

Solution

Draw the component twice, with the darker shadow behind and the “real” color, slightly offset, in front.

Discussion

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.206.225