package myWidgets;//======================================================================//  PROJECT:            _programming.java_//  FILE:               GraphicButton.java//  PURPOSE:            Chapter 12 lablet//  VERSION:            2.0//  TARGET:             Java v1.1//  UPDATE HISTORY:     2.0     12/4/98    1.1 event model//                      1.0     8/1/97    the version in _p.j_//======================================================================//------------------------------- NOTES --------------------------------/*    Here's how to use a GraphicButton:         INITIALIZATION        To construct a GraphicButton, supply the constructor with an array        of two images, and an optional label.  In the array of images,        image[0] should be the down image and image[1] the up.                NOTE: While not required, it's a good idea for the images to be        the same size. This class uses the size of the down image to        center the label.            EVENT HANDLING        A GraphicButton object responds to MOUSE_ENTERED and MOUSE_EXITED        events by hiliting and de-hiliting its label.  It responds to        MOUSE_PRESSED and MOUSE_RELEASED events by redrawing the button        in its appropriate state (down or up, respectively).               We've implemented an addActionListener() method, so when a         GraphicButton processes a MOUSE_RELEASED event, it sends        a new ActionEvent to all registered listeners, just like        an ordinary AWT Button.            ACCESSORS, MUTATORS        getLabel():	Returns the label string.        setLabel():	Sets the label string to the argument and resizes this object to fit.*///------------------------------ IMPORTS -------------------------------	import java.awt.*;import java.awt.event.*; //======================= GraphicButton CLASS ==========================/** * A GraphicButton has the same functionality as an ordinary AWT button: * it responds to mouse clicks by generating ActionEvents, and it keeps * track of all listeners that have registered themselves. * The primary difference is that it uses images for its up and down displays. */public class GraphicButton extends Canvas implements MouseListener{    private final int        LABEL_INSET  = 15;    private final Color      UP_COLOR     = Color.darkGray;    private final Color      DOWN_COLOR   = Color.white;    private final Color      HILITE_COLOR = Color.red;    protected Image[]        theImage;          // 0 -> is down, 1 -> is up    private   String         theLabel;    private   int            thisWidth,                             thisHeight,                             labelBase;    private   ActionListener listeners = null;  // all the registered listeners    protected int            curImage = 1;				//------------- Constructors and initialization utility ------------					    /**     * Construct a GraphicButton with two images and a label.     */    public GraphicButton(Image[] imgs, String label)    {        theLabel = label;        theImage = imgs;        setFont(new Font("Helvetica", Font.BOLD, 10));        fitLabel();                addMouseListener(this);    }					    /**     *	Construct a GraphicButton with two images and no label.     */    public GraphicButton(Image[] imgs)    {        this(imgs, null);	// Call the other constructor.    }	    /**     * Size the button so that there is a LABEL_INSET pixel inset on     * each side of the labeland the label is centered vertically     * in the button.     */    private void fitLabel()    {        thisHeight = theImage[0].getHeight(this) - 4;        if (theLabel != null)        {            FontMetrics fm = getFontMetrics(getFont());            thisWidth = 2 * LABEL_INSET + fm.stringWidth(theLabel);            labelBase = (thisHeight + fm.getAscent() - fm.getDescent()) / 2;        }        else        {            thisWidth = 3 * LABEL_INSET;        }    }		//------------------------ Event handlers --------------------------        /**     * Register a new listener for action events that we'll trigger     * from this object. The AWTEventMulticaster keeps track of all     * the listeners that have registered with this object and will     * broadcast any event we want to all the listeners.     */     public synchronized void addActionListener(ActionListener who)     {          // "listeners" is a chain of registered listeners.          // This statement adds the argument to the chain.          listeners = AWTEventMulticaster.add(listeners, who);     }	    /**     * Change the button state to down.     */    public void mousePressed(MouseEvent e)    {        curImage = 0;        repaint();    }	    /**     * Change the button state to up and send an action event     * to all registered listeners.     */    public void mouseReleased(MouseEvent e)    {        curImage = 1;        repaint();        // Make a new action event to send out,        ActionEvent ae = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, theLabel);                // and let the AWTEventMulticaster tell each registered listener        // to activate its own actionPerformed() method on the new event.        listeners.actionPerformed(ae);    }        /**     * Do nothing in response to a mouse click, since we     * have already done all the necessary handling in the     * mousePressed() and mouseReleased() methods.     */    public void mouseClicked(MouseEvent e)    { }	    /**     * Deal with a MOUSE_ENTERED event by hilighting the label of the button.     */    public void mouseEntered(MouseEvent e)    {        Graphics g = getGraphics();        g.setColor(HILITE_COLOR);        g.drawString(theLabel, LABEL_INSET, labelBase);    }	    /**     * Turn off hilighting when the mouse leaves this object.     */    public void mouseExited(MouseEvent e)    {        paintLabel(this.getGraphics());    }		//--------------------------- Graphics -----------------------------	    /**     * For flicker-free animation in the AnimatedButton subclass.     */    public void update(Graphics g)    {        paint(g);    }	    /**     * Redraw the image and paint the label on top of it.     */    public void paint(Graphics g)    {        g.drawImage(theImage[curImage], 0, 0, thisWidth, thisHeight, this);			        if (theLabel != null)        {            paintLabel(g);        }    }        /**     * Paint the label in the appropriate color.     * CALLED BY: mouseExited(), paint()     */    private void paintLabel(Graphics g)    {        if (curImage > 0)        {            g.setColor(UP_COLOR);        }        else        {            g.setColor(DOWN_COLOR);        }        g.drawString(theLabel, LABEL_INSET, labelBase);    }		//--------------------- Accessors, mutators ------------------------	    /**     * Return a copy of the label string.     */    public String getLabel()    {        return new String(theLabel);    }	    /**     * Set the label text, center it, and update the drawing.     */    public void setLabel(String s)    {        theLabel = s;        fitLabel();        repaint();    }}