import java.awt.*;
public class QuickCoolButton extends Canvas
{
//Button labels and font name
public String
font,firstlabel,secondlabel;
public Font fnt;//font for the label
public int
fontsize; //size of
label font
public Color c; //color of label text
public Dimension
QuickCoolButtonsize; //size
of button
/**
* Three booleans to test
if :
* 1) the mouse is down
* 2) the
enablebutton()/disablebutton() method was called by
*
the parent applet
* 3) the mouse is
inside/outside button area
**/
//Is the
mouse down? default => false
private boolean
is_the_mouse_down = false;
//true =>
enable the button
private boolean
you_want_to_disableMe = false;
//Has the mouse entered the button area ?
private boolean
is_mouse_in_button_area = false;
//false => paintNormalFlatButton(), true
=> paintRaisedButton()
/**
* Default
constructor
**/
public QuickCoolButton()
{
//Nothing spectacular happening :)
super();
}
/********************************************************************
* Constructor : String
firstlabel - text of the 1st button's label *
*
(1) : 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 QuickCoolButton(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);
}
/****************************************************************
* If user wants to have only
one button, user can specify only *
* ONE label string and that
will be used as longest string *
****************************************************************/
/********************************************************************
* Constructor : String
firstlabel - text of the 1st button's label *
*
(2) : 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 QuickCoolButton(String
firstlabel, //1st label
only
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);
}
/**
* Modifier method of
QuickCoolButton 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
QuickCoolButton label
**/
public String getButtonLabel()
{
return firstlabel;
}
/**
* 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.
The default size of Canvas is (0, 0).
**/
public Dimension
preferredSize()
{
//must over-ride this, or there is NO
canvas to draw!
return
QuickCoolButtonsize;
}
/**
* 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
QuickCoolButtonsize;
}
/**
* Creates the
peer. This peer allows you to change the
* user interface of the
canvas without changing its functionality.
**/
public void addNotify()
{
super.addNotify();
/*****************************************************
* 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
*
*****************************************************/
QuickCoolButtonsize =
measureMe();
}
//measureme for equal
buttons
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) ;
}
}
/**
* Disables
QuickCoolButton.
**/
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
QuickCoolButton.
**/
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;
}
/**
* Calls the
appropriate paint() method of QuickCoolButton
* according to the
button states
**/
public void paint(Graphics g)
{
//Check
conditions and make method calls accordingly
if(is_the_mouse_down)
{
/**
* if mouse is DOWN draw a
* down state/DISABLED button
**/
paintDepressedButton(g);
}
else
{
/**
* Else draw a up state/NORMAL button
**/
paintNormalFlatButton(g);
}
/************/
if(is_mouse_in_button_area)
{
/**
* If mouse has ENTERED button area,
* then draw a RAISED/up state button
**/
paintRaisedButton(g);
}
else
{
/**
* Else If mouse has EXITED button area,
* then draw a RAISED/up state button
**/
paintNormalFlatButton(g);
}
/************/
if(is_the_mouse_down && is_mouse_in_button_area )
{
/**
* if mouse is down AND mouse is INSIDE
* button area, then draw a DEPRESSED/down
* state button
**/
paintDepressedButton(g);
}
/************/
if(you_want_to_disableMe)
{
/**
* If parent has asked that button be disabled,
* then draw a down state/DISABLED button
**/
paintDisabledButton(g);
}
if((is_the_mouse_down) && !(is_mouse_in_button_area))
{
/**
* If mouse is down AND it is OUTSIDE
* button area, then draw a down state /
* DEPRESSED button
**/
paintDepressedButton(g);
}
}
/************************************
* QUICKCOOLBUTTON
PAINTING ROUTINES *
************************************/
/**
* Paints the
'NORMAL BORDERLESS & ENABLED' QuickCoolButton
**/
protected void paintNormalFlatButton(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;
//Refresh the area to be painted
g.clearRect(0,0,w-1,h-1);
//Set the button color
g.setColor(Color.gray);
/**
* No
drawing borders. We want a FLAT button like MSIE or
*
Netscape Coomunicator 4.02
**/
//Button label drawing
g.setColor(Color.white);
//Shadow of
label text
g.drawString(firstlabel,drawfontx+1,drawfonty+1);
//Actual
label text. Button is active,
//so make label color darker
g.setColor(c.darker());
g.drawString(firstlabel,drawfontx,drawfonty);
}
/**
* Paints the
'DISABLED' QuickCoolButton
**/
protected void paintDisabledButton(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;
//Refresh the area to be painted
g.clearRect(0,0,w-1,h-1);
//Refer QuickPanel code in the paint method for etched panel
g.setColor(Color.gray);
//Draw Line : top-left to bottom-left
g.drawLine(0, 0, 0, h - 1);
//Draw Line : top-left to top-right
g.drawLine(0, 0, w - 1, 0);
g.setColor(Color.white);
//Draw Line : top-left to bottom-left
g.drawLine(1, 1, 1, h - 2);
//Draw Line : top-left to top-right
g.drawLine(1, 1, w -
3, 1);
g.setColor(Color.gray);
//Draw Line : bottom-left to bottom-right
g.drawLine(0, h - 1, w - 1,
h - 1);
//Draw Line : top-right to bottom-right
g.drawLine(w - 1, 2, w - 1,
h);
g.setColor(Color.white);
//Draw Line : bottom-left to bottom-right
g.drawLine(0, h, w, h);
//Draw Line
: top-right to bottom-right
g.drawLine(w, 0, w, h);
//Button
label drawing
g.setColor(Color.darkGray);
//Shadow of
label text
g.drawString(firstlabel,drawfontx+1,drawfonty+1);
//Actual
label text. Button is disabled so make label color gray
g.setColor(Color.gray);
g.drawString(firstlabel,drawfontx,drawfonty);
}
/**
* Paints the
'RAISED BORDER ACTIVATED' QuickCoolButton
* Activated
means that mouse is over the button.
**/
protected void paintRaisedButton(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;
//Refer QuickPanel code in the paint
method for raised panel
g.setColor(Color.black);
// Draw lines : bottom-left to bottom-right
g.drawLine(0, h, w - 1, h);
g.drawLine(0+1, h-1, w - 2,
h-1);//for a 'thick' line
//Draw lines
: top-right to bottom-right
g.drawLine(w, 0, w, h);
g.drawLine(w-1, 0+1, w-1,
h-1);
g.setColor(Color.darkGray);
//Draw lines
: bottom-left to bottom-right
g.drawLine(0 + 1 +1, h - 1
-1, w - 2 -1, h - 1 - 1);
//Draw line
: top-right to bottom-right
g.drawLine(w - 1 -1, 0 + 1 +
1, w - 1 -1, h - 1-1);
g.setColor(Color.white);
//Draw lines : top-left to bottom-left
g.drawLine(0, 0, 0, h - 1);
g.drawLine(0+1, 0, 0+1, h -
1 -2); //for a 'thick'
line
//Draw lines : top-left to top-right
g.drawLine(0, 0, w - 1, 0);
g.drawLine(0+1, 0+1, w -
1-1, 0+1);//for a
'thick' line
//Button label drawing
g.setColor(Color.white);
//Shadow of
label text
g.drawString(firstlabel,drawfontx+1,drawfonty+1);
//Actual
label text. Button is active, so make label color brighter
g.setColor(c.brighter());
g.drawString(firstlabel,drawfontx,drawfonty);
}
/**
* Paints the
'DEPRESSED DOWN STATE' QuickCoolButton
**/
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;
//Refresh the area to be
painted
g.clearRect(0,0,w-1,h-1);
//Refer QuickPanel code in the paint method for
sunken panel
g.setColor(Color.darkGray);
//Draw lines
: top-left to top-right
g.drawLine(0, 0, w - 1, 0);
g.drawLine(0+1, 0+1, w - 2,
0+1);//for a 'thick'
line
//Draw lines
: top-left to bottom-left
g.drawLine(0, 0, 0, h - 1);
g.drawLine(0+1, 0+1, 0+1,
h-1-1);//for a 'thick'
line
g.setColor(Color.black);
//Draw line
: top-left to top-right
g.drawLine(1+1, 1+1, w -
2-1, 1+1);
//Draw line
: top-left to bottom-left
g.drawLine(1+1, 1+1, 1+1, h
- 2-1);
g.setColor(Color.white);
//Draw lines
: bottom-left to bottom-right
g.drawLine(0, h, w, h);
g.drawLine(1, h - 1, w - 1,
h - 1); //for a 'thick' line
g.drawLine(1+1, h - 1-1, w -
1-1, h - 1-1); //for a 'thick' line
//Draw lines
: top-right to bottom-right
g.drawLine(w, 0, w, h);
g.drawLine(w - 1, 1, w - 1,
h - 1); //for a 'thick' line
g.drawLine(w - 1 -1, 1+1, w
- 1 -1 , h - 1 - 1); //for a 'thick' line
//Button
label drawing
g.setColor(Color.darkGray);
//Shadow of
label text
g.drawString(firstlabel,drawfontx+3,drawfonty+3);
//Actual
label text. Button is active but DEPRESSED, so make label color lightGray
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)
{
//condition satisfied, so 'post' the
event
buttonwasClicked();
is_the_mouse_down = false;
repaint();
}
//handle the event here itself
return true ;
}
public boolean mouseDrag (Event evt,
int x, int y)
{
return true ;
}
public boolean mouseEnter(Event evt, int
x, int y)
{
//mouse has
entered button area so set boolean true
is_mouse_in_button_area =
true;
repaint();
return true;
}
public boolean mouseExit(Event evt,
int x, int y)
{
//mouse has left button area so set boolean
false
is_mouse_in_button_area =
false;
repaint();
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 mouseUp 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 :)
See the QuickCoolButton Applet
in action here.