/*
 * Filename: QuickButton1.java
 * Written By: Sunit Katkar
 * E-Mail:sunitkatkar@hotmail.com
 * Home-Page : www.vidyut.com/sunit
 * Java Page : www.vidyut.com/sunit/JavaPage.html
 ***************************************************************
 * Description:
 * Are you bored waiting for an image to download in a applet ?
 * Do you site behind a firewall? Does a ImageButton which you see
 * everywhere take long to load ? Then here is a simple NON-IMAGE
 * yet somewhat attractive and configurable button which loads
 * quickly.
 *
 * What's NEW in this version :
 * You can have same sized buttons. All you have to do is -
 * a) plan what will the (text) labels for each button.
 * b) pass the text string you want for a button followed
 *    by the LONGEST string you have planned for a button
 ***************************************************************
 * Copyright (c) 1997 Sunit Katkar All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * for NON-COMMERCIAL or COMMERCIAL purposes and without fee
 * is hereby granted.
 *
 * Whew ! That was too much legalese..even to have copied and pasted
 * from some other place... PLEASE DO NOT BLAME ME in any way
 * if your system crashes because of this code, or if anything else
 * bad happens. In short "DO WHAT YOU WANT BUT DONT BLAME ME !"
 */
 *****************************************************************/

import java.applet.*;
import java.awt.*;

//Extend a canvas for our custom widget
public class QuickButton1 extends Canvas
{
        public  String font,firstlabel,secondlabel;
        public  Font fnt;
        public  int fontsize ;
        public  Color c;
        public  Dimension QuickButtonsize;

       /**
        * Two booleans to test if the mouse is down and to see
        * if the enablebutton()/disablebutton() method was
        * called by the parent applet
        **/

        //Is the mouse down? default => false
        private boolean is_the_mouse_down = false;
        //true => enable the button
        private boolean you_want_to_disableMe = false;

       /**
        * Default constructor
       **/
        public QuickButton1()
        {
                //Nothing spectacular happening :)
                super();
        }

   /************** WHATS NEW !*****************************************
   * Constructor : String firstlabel - text of the 1st button's label
   *             : String secondlabel - text of the 2nd button's label
   *             : String font  -  Font to construct the label
   *             : int fontsize - Size of font
   *             : Color c      - Color to use as foreground of label
   ********************************************************************/

   public QuickButton1(String firstlabel, //1st label
                       String secondlabel,//put the longest label you plan here
                       String font,
                       int fontsize,
                       Color c)
   {
                this.firstlabel = firstlabel;
                this.secondlabel = secondlabel;
                this.font = font;
                this.fontsize = fontsize;
                this.c = c;
                //We use a fixed Font style, try changing this to suit your
                //needs. Maybe include this style parameter in the constructor
                fnt = new Font(font,Font.BOLD,fontsize);
   }

   /************** WHATS NEW !*****************************************
   * This construtor is for creating just one button, so secondlabel is
   * not required. Possibly, this can be used for a single button in 
   * a dialog box, etc.
   * Constructor : String firstlabel - text of the 1st button's label
   *             : String font  -  Font to construct the label
   *             : int fontsize - Size of font
   *             : Color     - Color to use as foreground of label
   ********************************************************************/

   public QuickButton1(String firstlabel, //1st label
                       String font,
                       int fontsize,
                       Color c)
   {
        this.firstlabel = firstlabel;
        this.secondlabel = firstlabel;
        this.font = font;
        this.fontsize = fontsize;
        this.c = c;
        //We use a fixed Font style, try changing this to suit your
        //needs. Maybe include this style parameter in the constructor
        fnt = new Font(font,Font.BOLD,fontsize);
   }


 /**
  * Returns the preferred size of this component. This method has to be
  * over-ridden, as it is called during addNotify() to establish the initial
  * size of the Canvas, and the default size is (0, 0).
 **/
    public Dimension preferredSize()
    {
      //must over-ride this, or there is NO canvas to draw!
                return QuickButtonsize;
    }
 /**
  * Returns the minimum size of this component. This method has to be
  * over-ridden, as it is called by many layout managers. Connected AWT
  * components call the peer for this information.
 **/
    public Dimension minimumSize()
        {
      //must over-ride this, or the layout manager
          //may not function as desired
        return QuickButtonsize;
        }
 /**
  * Creates the peer.  This peer allows you to change the
  * user interface of the canvas without changing its functionality.
 **/
    public void addNotify()
    {
        super.addNotify();
       /************ WHATS NEW ! ****************************
       * Button size is dependent on the fontmetrics of the *
       * secondlabel and its font.                          *
       * For instance, we are measuring the stringWidth()   *
       * of the secondlabel and then adjusting size of      *
       * 1st button                                         *
       *****************************************************/
        QuickButtonsize = measureMe();
    }

    protected Dimension measureMe()
    {
        FontMetrics fmt = this.getFontMetrics(fnt);
        if (fmt == null)
        {
            return new Dimension(0,0);
        }
        else
        {
            //added pixels for visual adjustment
            //Note that here we measure width of the secondlabel,
            //which is the longest string among the buttons you have
            //planned.
            int width =   fmt.stringWidth(secondlabel)+15;
            int actualheight = fmt.getHeight()+ fmt.getAscent() +5;
            int height = actualheight;
            return new Dimension(width,height) ;
        }
    }

 /**
  * Modifier method of QuickButton1 label
 **/
 public void setButtonLabel(String firstlabel)
 {
     //set the button label
     this.firstlabel = firstlabel;
    /**
     * refresh display as we want to see effect
     * immediately; and not wait for user to take the
     * mouse over the button.
    **/
    repaint();
 }

 /**
  * Accessor method for QuickButton1 label
 **/
 public String getButtonLabel()
 {
    return firstlabel;
 }

 /**
  * Disables QuickButton1.
 **/
        protected boolean disablebutton()
        {
                //Call the disable() method of super class java.awt.Component
                //from which the Canvas is derived and our QuickButton1 is
                //derived from Canvas
                super.disable();
                //set the boolean to true indicating that parent asked
                //that the button be disabled.
                you_want_to_disableMe = true;
                //Call repaint to refresh button display
                repaint();
                //return true as this action has been performed
                return true;
        }
 /**
  * Enables QuickButton1.
 **/
    protected boolean enablebutton()
    {
        //Call the enable() method of super class java.awt.Component
        //from which the Canvas is derived and our QuickButton1 is
        //derived from Canvas
        super.enable();
        //set boolean to false that you set to true in disablebutton()
        you_want_to_disableMe = false;
        //Call repaint to refresh button display
        repaint();
        //return true as this action has been performed
        return true;
    }

  /**
   * Paints the QuickButton1
  **/
        public void paint(Graphics g)
        {
            //Check conditions and make method calls accordingly
            if(is_the_mouse_down || you_want_to_disableMe)
            {
                 //if mouse is down or parent asked to
                 //disable this button  draw a down state/disabled button
                paintDepressedButton(g);
            }
            else
            {
                 //draw a normal button
                 paintNormalButton(g);
            }
        }

        protected void paintNormalButton(Graphics g)
        {
          //set the font
          g.setFont(fnt);

          //Get the required width and height of the button
          int w = measureMe().width;
          int h = measureMe().height;
          //Again calculate the font height & width
          int fonttotalheight = g.getFontMetrics().getHeight()
                                + g.getFontMetrics().getLeading();
          //Get the stringwidth of the firstlabel
          int fonttotalwidth = g.getFontMetrics().stringWidth(firstlabel);
          int drawfonty = (h-((h - fonttotalheight)/2)-4);
          int drawfontx = ((w - fonttotalwidth)/2)+2;

          //These set the button background color - try changing these
          g.setColor(Color.lightGray);
          g.fill3DRect(0,0,w-1,h-1,true);
          g.setColor(Color.lightGray);
          g.setColor(Color.white);
          g.drawString(firstlabel,drawfontx+1,drawfonty+1);
          g.setColor(c);
          g.drawString(firstlabel,drawfontx,drawfonty);

        }

        protected void paintDepressedButton(Graphics g)
        {
          g.setFont(fnt);
          int w = measureMe().width;
          int h = measureMe().height;
          int fonttotalheight = g.getFontMetrics().getHeight()
                              + g.getFontMetrics().getLeading();
          //Get the stringwidth of the firstlabel
          int fonttotalwidth = g.getFontMetrics().stringWidth(firstlabel);
          int drawfonty = (h-((h - fonttotalheight)/2)-4);
          int drawfontx = ((w - fonttotalwidth)/2)+2;

          g.setColor(Color.lightGray);
          g.fill3DRect(0,0,w-1,h-1,false); //changed in this version from true to false
          g.setColor(Color.black);
          g.drawString(firstlabel,drawfontx+3,drawfonty+3);
          g.setColor(Color.lightGray);
          g.drawString(firstlabel,drawfontx+2,drawfonty+2);

        }

        /**
         * Mouse handling routines
        **/
        public boolean mouseDown (Event evt, int x, int y)
        {
            is_the_mouse_down = true;
            repaint();
            //handle the event here itself
            return true;
        }

        public boolean mouseUp (Event evt, int x, int y)
        {
                //Check whether a mouse down occured on the button
                //and if it did we ned to 'post' this event
                if(is_the_mouse_down)
                {
                    buttonwasClicked();
                    is_the_mouse_down = false;
                    //handle the event here itself
                    repaint();
                }
            return true ;
        }

        public boolean mouseDrag (Event evt, int x, int y)
        {
            return true ;
        }
        public boolean mouseEnter(Event evt, int x, int y)
        {
            return true;
        }

        public boolean mouseExit(Event evt, int x, int y)
        {
                return true;
        }
        /**
         *      Action handling routines
        **/
        public boolean action(Event e, Object o)
        {
                //Let parent applet handle this,
                //as parent may want to enable/disable certain
                //instances of this button depending on
                //certain conditions. Hence return false
                return false;
        }
        /**
         * If mouse is down on a button and a mouse up follows
         * It means that user wants to 'click' our button.
         * So we need to 'post' a event to the parent
        **/
        public void buttonwasClicked()
        {
                Event theEvent = new Event(this, Event.ACTION_EVENT, firstlabel);
                postEvent(theEvent);
        }

 }//All ends :)

The source code for the applet that uses this class is here. See the applet in action.