Blackberry Custom Button Field
March 31, 2008
The Blackberry’s ButtonField doesn’t allow much customisation of how it looks. It is grey when not selected, and when selected it is highlighted. The highlight colour depends on the current theme. The image below shows a ButtonField in the unselected state, and in the selected state with different themes.

Because the ButtonField doesn’t allow you to customise its appearance you must create your own custom field if you wish to do so. My CustomButtonField class below is almost identical to the standard ButtonField, only it allows you to specify the the highlight colour. It also displays the text in white even when the button isn’t selected
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
public class CustomButtonField extends Field
{
private int backgroundColour = Color.GRAY;
private int highlightColour;
private int fieldWidth;
private int fieldHeight;
private String text;
private int padding = 8;
public CustomButtonField(String text, int highlightColour)
{
super(Field.FOCUSABLE);
this.text = text;
this.highlightColour = highlightColour;
Font defaultFont = Font.getDefault();
fieldHeight = defaultFont.getHeight() + padding;
fieldWidth = defaultFont.getAdvance(text) + (padding * 2);
this.setPadding(2, 2, 2, 2);
}
protected boolean navigationClick(int status, int time)
{
fieldChangeNotify(1);
return true;
}
protected void onFocus(int direction)
{
backgroundColour = highlightColour;
invalidate();
}
protected void onUnfocus()
{
backgroundColour = Color.GRAY;
invalidate();
}
public int getPreferredWidth()
{
return fieldWidth;
}
public int getPreferredHeight()
{
return fieldHeight;
}
protected void layout(int arg0, int arg1)
{
setExtent(getPreferredWidth(), getPreferredHeight());
}
protected void drawFocus(Graphics graphics, boolean on)
{
}
protected void fieldChangeNotify(int context)
{
try
{
this.getChangeListener().fieldChanged(this, context);
}
catch (Exception e)
{}
}
protected void paint(Graphics graphics)
{
graphics.setColor(backgroundColour);
graphics.fillRoundRect(0, 0, fieldWidth, fieldHeight, 8, 8);
graphics.setColor(Color.GRAY);
graphics.drawRoundRect(0, 0, fieldWidth, fieldHeight, 8, 8);
graphics.setColor(Color.WHITE);
graphics.drawText(text, padding - 1, padding / 2 + 1);
}
}
You can see the CustomButtonFieldin the image below, which shows it unselected and also selected with a highlight colour of 0×990099.

If you want to go beyond changing the colours of your buttons then Jonathan Fisher has written up details of a custom BigButtonField that uses images, allowing you to create some really great looking buttons.
Your constructor includes a call to the method setPadding(), class is this method from?
Thanks.
Comment by Jesus — July 8, 2008 @ 12:03 am
The setPadding method is part of the Field class. Since you asked I’ve done some investigation and it doesn’t seem to be documented anywhere, which is quite strange.
I’m using Eclipse for development, and it shows that Field has two setPadding methods:
setPadding(int, int, int, int);
setPadding(XYEdges);
I’m using version 4.2.1 of the API.
Comment by admin — July 11, 2008 @ 7:23 am
Great bit of code cheers! I added the method below to mine so the return and space key can click the button as well just like the standard ButtonField.
Add import net.rim.device.api.system.*; to your import list.
public boolean keyChar(char key, int status, int time)
{
boolean retval = false;
if (key == Characters.ENTER || key == Characters.SPACE)
{
fieldChangeNotify(1);
retval = true;
} else {
retval = super.keyChar(key,status,time);
}
return retval;
}
Comment by Ben — November 5, 2008 @ 10:48 am
Nice Code! I’m new to this – so I will post back and let you know what I find out. Thanks.
Comment by Boca Raton Attorney — December 5, 2008 @ 1:16 pm
Tried this out – Works great – Thanks!
Comment by Boston Raton Attorney — December 17, 2008 @ 2:42 pm
hey..
umm I don’t know if your code is jacked up or whatnot. But when I go from a text field to custombuttonfield, then back to the text field.. the button stays the color.. doesn’t change back to grey.
Comment by afallenhope — January 28, 2009 @ 5:43 pm
Keep up the great work!
I have same issue as afallenhope, if I change background color to blue, when button loses focus, button color reverts to gray.
It would be also nice to be able to optionally pass in width and other values.
Comment by mart — May 26, 2009 @ 1:48 pm
another issue… when I use this button to open another screen with pushScreen(), on the trip back, the first screen is sometimes skipped entirely and exits to blackberry “desktop”. Maybe it is a isDirty() issue?
Comment by mart — May 26, 2009 @ 3:22 pm
please disregard/remove previous post. Issue was entirely self-inflicted. Code works properly.
Comment by mart — May 26, 2009 @ 4:50 pm
Since this isn’t mention explictly here…thru trial and error I have figured out the padding params are top, left, bottom, right.
Comment by elio — July 16, 2009 @ 8:34 pm
It is very basic to start with the customisation..
Thanks for the detailed, simple and clear example.
Comment by PraveenGoparaju — July 21, 2009 @ 11:39 am
I’ve learned (painfully) that using setPadding is not a good idea. Not only is it not mentioned / documented / supported, it doesn’t exist in some cases. The result is an uncaught exception and unhappy non-users.
I have yet to find a suitable replacement for a pre-4.60 device. In 4.6, an empty border works fine.
Comment by _Jon — July 21, 2009 @ 6:49 pm
Hi _Jon,
Thanks for the feedback. I’ve never ran into any problems with setPadding myself (on pre and post 4.6 devices), but thanks for the warning!!
Ben
Comment by Ben — July 21, 2009 @ 7:01 pm
I am using setPadding(int, int, int, int);
But the Eclipse 4.2.1 and 4.3 doesn’t seem to support setPadding.
It is working perfectly on 4.5 and above.
I have used setPadding for EditField, PasswordEditField and RichTextField and the compiler gives me this error
the method setPaddin(int,int,int,int) is undefined for the above fields.
Comment by Safy — July 23, 2009 @ 5:30 am
But the Eclipse 4.2.1 and 4.3 doesn’t seem to support setPadding.
It is working perfectly on 4.5 and above.
I have used setPadding for EditField, PasswordEditField and RichTextField and the compiler gives me this error
the method setPaddin(int,int,int,int) is undefined for the above fields.
Comment by Safy — July 23, 2009 @ 5:31 am
What program do I use the code with/for?
Comment by Brian — August 14, 2009 @ 3:41 am
@Brian – a Blackberry mobile phone. You need either the JDE or Eclipse plugin for Blackberry development. See http://na.blackberry.com/eng/developers/
Comment by Ben — August 20, 2009 @ 10:52 pm
Hey this is excellent bit of code im just new to this whole BB dev stuff and this was really helpful. Is it possible to use layout managers to layout the button?
Comment by kharn — October 7, 2009 @ 11:11 am
Hi Kharn,
Glad you found it useful. Yes, the button will be positioned based on the layout manager you are using, the same as any other field.
Ben
Comment by Ben — October 7, 2009 @ 12:48 pm