> hey i want to create a customized JButton.......... can anyone help me
> out plz........ i want to create a button in any given shape (say e.g.
> in the shape of an animal like elephant or dog or etc...) so how can i
> change the shape of a button??????? i do NOT want to, however, display
> an image on the button rather want to reshape the button in that
> form.....plz help
This is not JButton overriden, but it might give you some ideas.
This is a nice looking hyperlink component derived from JComponent.
The code is mine and it is just released under BSD license.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class ActiveLabel extends JComponent {
public final int XMARGIN=2,YMARGIN=2;
public final int ACTIVE=1,IDLE=0,PRESSED=2;
static final Color[] clr = { Color.blue, Color.red, Color.black };
ActionListener lst;
String txt,cmd;
public int state;
int align;
// ctor
public ActiveLabel(String str,int alg)
{
align=alg;
cmd=txt=str;
state=IDLE;
enableEvents(AWTEvent.MOUSE_EVENT_MASK );
lst=null;
}
public ActiveLabel(String str)
{
this(str,Label.LEFT);
}
public ActiveLabel()
{
this("",Label.LEFT);
}
// paint
public void paint(Graphics g)
{
FontMetrics fm=getFontMetrics(getFont());
int wt=fm.stringWidth(txt);
int ht=fm.getHeight();
Rectangle r=getBounds();
int w=r.width;
int h=r.height;
int x=(w-wt) >> 1;
int y=((h+ht) >> 1)-2;
if(align == Label.LEFT) x=0;
else if(align == Label.RIGHT) x=w-wt;
g.setColor(clr[state]);
g.drawString(txt,x,y);
g.drawLine(x,y+1,x+wt,y+1);
}
// getMinimumSize
public Dimension getMinimumSize()
{
FontMetrics fm=getFontMetrics(getFont());
int h=fm.getHeight() + YMARGIN + YMARGIN;
int w=fm.stringWidth(txt) + XMARGIN + XMARGIN;
return new Dimension(w,h);
}
// minimumSize
public Dimension minimumSize()
{
return getMinimumSize();
}
// preferredSize
public Dimension preferredSize()
{
return getMinimumSize();
}
// getPreferredSize
public Dimension getPreferredSize()
{
return getMinimumSize();
}
//
public void released()
{
int a=state;
state=ACTIVE;
if(a != state) repaint();
postAction();
}
//
public void pressed()
{
int a=state;
state=PRESSED;
if(a != state) repaint();
}
//
public void entered()
{
int a=state;
state=ACTIVE;
if(a != state) repaint();
}
//
public void exited()
{
int a=state;
state=IDLE;
if(a != state) repaint();
}
//
public void processEvent(AWTEvent e)
{
if(e.getID() == MouseEvent.MOUSE_PRESSED) pressed();
else if(e.getID() == MouseEvent.MOUSE_ENTERED) entered();
else if(e.getID() == MouseEvent.MOUSE_EXITED) exited();
else if(e.getID() == MouseEvent.MOUSE_RELEASED) released();
super.processEvent(e);
}
//
public void setActionCommand(String c)
{
cmd=c;
}
//
public void addActionListener(ActionListener l)
{
lst=AWTEventMulticaster.add(lst,l);
}
//
public void removeActionListener(ActionListener l)
{
lst=AWTEventMulticaster.remove(lst,l);
}
//
private void postAction()
{
if(lst != null)
{
ActionEvent event = new
ActionEvent(this,ActionEvent.ACTION_PERFORMED,cmd);
lst.actionPerformed(event);
}
}
}
Alex Hunsley - 12 Apr 2006 01:04 GMT
> This is not JButton overriden, but it might give you some ideas.
> This is a nice looking hyperlink component derived from JComponent.
[quoted text clipped - 10 lines]
> static final Color[] clr = { Color.blue, Color.red, Color.black };
> ActionListener lst;
Thanks for contributing your code, Drazen!
A little feedback for you...
Are you aware that class members without an explicit access modifier
(private, protected or public) are made public to other classes in the
same package? So any class in the same package can reach in and directly
read (or modify) your ActionListener list which breaks encapsulation. If
something should be private, I suggest you make it explicitly private.
Also, I suggest that you mark your constants 'static' as well as final,
e.g.:
public static final int XMARGIN=2,YMARGIN=2;
^^^^^^
[snip]
> public void paint(Graphics g)
> {
> FontMetrics fm=getFontMetrics(getFont());
[snip]
Btw, it's usual to override paintComponent rather than paint, unless you
have good reason. By overriding paint directly you are breaking the
rendering of any borders that may have been set on the component...
Also I notice your component has its text set at construction time, and
the text doesn't change thereafter. So it's a little wasteful to do
those calculations on the size of the text etc. each and every time
paint gets called (or getMinimumSize) - you may as well siphon off that
work into a seperate method, and only call it the first time it is
needed, and then cache the results for later reuse.
Drazen Gemic - 12 Apr 2006 13:35 GMT
Thanks for the suggestion. This class was created in a very short
time and it is a part of a project that was (yes, I swear it was),
finished on schedule.
DG
Alex Hunsley - 12 Apr 2006 18:21 GMT
> Thanks for the suggestion. This class was created in a very short
> time and it is a part of a project that was (yes, I swear it was),
> finished on schedule.
Well, if you ever feel like doing some refactoring, you have some
suggestion handy!
cheers,
alex