BlackBerry customized HorizontalFieldManager - blackberry

In Blackberry I want to create a class that extends HorizontalFieldManager so that I can display a label and an image on the same line with the label to the left and the image to the right.
I want the user to be able to interact with the HorizontalFieldManager as if it were a single field. I also want each HorizontalFieldManager to be focusable when added to a VeriticalFieldManager. I also want the clcik action events.

Sounds like you'll be wanting to start writing your own Field classes, here's an example to get you started:
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
public class SimpleField extends Field {
private String label;
private Bitmap image;
private int fieldWidth;
private int fieldHeight;
private boolean hover = false;
private int focusColor = 0xcccccc;
public SimpleField(String label, Bitmap image) {
super(Field.FOCUSABLE);
this.label = label;
this.image = image;
fieldWidth = Display.getWidth();
fieldHeight = image.getHeight();
}
protected void onFocus(int direction) {
hover = true;
invalidate();
super.onFocus(direction);
}
protected void onUnfocus() {
hover = false;
invalidate();
super.onUnfocus();
}
public int getPreferredWidth() {
return fieldWidth;
}
public int getPreferredHeight() {
return fieldHeight;
}
protected void layout(int width, int height) {
setExtent(fieldWidth, fieldHeight);
}
protected void paint(Graphics graphics) {
if(hover){
graphics.setColor(focusColor);
graphics.fillRect(0, 0, fieldWidth, fieldHeight);
}
graphics.drawText(label, 0, (fieldHeight - graphics.getFont().getHeight()) / 2);
graphics.drawBitmap(graphics.getFont().getAdvance(label), 0, image.getWidth(), image.getHeight(), image, 0, 0);
}
}

Related

wrapContent of Custom HorizontalFieldManager Blackberry

I am developing an app in which I need to display products in an expandable list. So I have tried an example which was given in stackoverflow... So, it is working good, but my problem is the divider that will not wrap (expand) based on content expanding, like in screen ...
as you can see, in the screen the date2 field is not displayed properly ..
for that, is there any scrolling facility or can this expand automatically?
Here is my code
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.FontFamily;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.TouchEvent;
import net.rim.device.api.ui.Touchscreen;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.NullField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
class UiMainscreen extends MainScreen implements FieldChangeListener
{
private CustomListField cu_field[];
private Bitmap image=null;
int size=8;
public UiMainscreen() {
VerticalFieldManager vmanager=new VerticalFieldManager(VERTICAL_SCROLL|VERTICAL_SCROLLBAR){
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth(),Display.getHeight());
setExtent(Display.getWidth(),Display.getHeight());
}
};
cu_field=new CustomListField[size];
for(int i=0;i<size;i++){
image=Bitmap.getBitmapResource("sample_"+i+".jpg");
cu_field[i]=new CustomListField("BlackBerry models that had a built-in mobile phone, were the first models that natively ran Java, and transmitted data over the normal 2G cellular network. RIM began to advertise these devices as email-capable mobile phones rather than as 2-way pagers.", image, "jan2011", 100, 100,Color.LIGHTGREEN);
cu_field[i].setChangeListener(this);
vmanager.add(new SeparatorField());
vmanager.add(cu_field[i]);
}
add(vmanager);
}
public void fieldChanged(Field field, int context) {
// TODO Auto-generated method stub
for(int i=0;i<size;i++){
if(field==cu_field[i]){
final int k=i;
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert("You click on Item No "+k);
}
});
}
}
}
}
class CustomListField extends HorizontalFieldManager{
private Bitmap scale_image;
private int width=0;
private int height=0;
private int background_color=0;
private BitmapField bitmap_field;
private boolean flag=false;
Bitmap logingBg;
public CustomListField(String title, Bitmap image, String date,int image_width,int image_height,int background_color){
super(NO_HORIZONTAL_SCROLL|USE_ALL_WIDTH);
this.background_color=background_color;
width=image_width;
height=image_width;
if(image!=null){
scale_image=new Bitmap(image_width, image_height);
image.scaleInto(scale_image, Bitmap.FILTER_LANCZOS);
bitmap_field=new BitmapField(scale_image);
flag=false;
bitmap_field.setMargin(5, 5, 5, 5);
add(bitmap_field);
}
VerticalFieldManager vmanager=new VerticalFieldManager(USE_ALL_WIDTH|Field.FIELD_VCENTER){
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth(), height);
setExtent(Display.getWidth(), height);
}
};
///////////////////////////////////////////
/* Bitmap logingBg = Bitmap.getBitmapResource("myorderdatebackground.png");
HorizontalFieldManager hfm = new HorizontalFieldManager(USE_ALL_WIDTH);
HorizontalFieldManager hfm2 = new HorizontalFieldManager(Field.FIELD_HCENTER);
ButtonField btnext = new ButtonField("btn");
CustomButtonField btnSignIn = new CustomButtonField(0, "", logingBg,
logingBg, Field.FOCUSABLE, Color.WHITE);
hfm2.add(btnext);
hfm.add(btnSignIn);
hfm.add(hfm2);
vmanager.add(hfm);*/
logingBg = Bitmap.getBitmapResource("myorderdatebackground.png");
HorizontalFieldManager HFM = new HorizontalFieldManager(USE_ALL_WIDTH) {
public void paint(Graphics g) {
//g.setBackgroundColor(Color.BLUE);
g.clear();
g.drawBitmap(0, 0, Display.getWidth(),
logingBg.getHeight(), logingBg, 0, 0);
super.paint(g);
}
};
HorizontalFieldManager lableRegistHFM = new HorizontalFieldManager(
FIELD_VCENTER);
LabelField RegistrationLbl = new LabelField("My Orders",Field.FIELD_HCENTER);
FontFamily fontFamily[] = FontFamily.getFontFamilies();
Font font11 = fontFamily[1].getFont(FontFamily.CBTF_FONT, 12);
font11 = fontFamily[1].getFont(Font.BOLD, 18);
RegistrationLbl.setFont(font11);
RegistrationLbl.setMargin(0, 0, 0, (Display.getWidth() / 3));
lableRegistHFM.add(RegistrationLbl);
HFM.add(lableRegistHFM);
vmanager.add(HFM);
/**************************************************************/
LabelField title_lbl=new LabelField("Title: "+title,Field.NON_FOCUSABLE|DrawStyle.ELLIPSIS);
vmanager.add(title_lbl);
LabelField date_lbl=new LabelField("Date: "+date,Field.NON_FOCUSABLE);
vmanager.add(date_lbl);
LabelField date_lbl3=new LabelField("Date2: "+date,Field.NON_FOCUSABLE);
vmanager.add(date_lbl3);
LabelField date_lbl4=new LabelField("Date2: "+date,Field.NON_FOCUSABLE);
vmanager.add(date_lbl4);
Font fon=title_lbl.getFont();
int title_height=fon.getHeight();
Font font=date_lbl.getFont();
int date_height=font.getHeight();
int pad=title_height+date_height;
title_lbl.setPadding((height-pad)/2, 0, 0, 0);
add(vmanager);
add(new NullField(FOCUSABLE));
}
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth(), height);
setExtent(Display.getWidth(), height);
}
protected void paint(Graphics graphics) {
if(flag)
graphics.setBackgroundColor(background_color);
graphics.clear();
super.paint(graphics);
}
protected void onFocus(int direction) {
super.onFocus(direction);
flag=true;
invalidate();
}
protected void onUnfocus() {
invalidate();
flag=false;
}
protected boolean navigationClick(int status, int time) {
if(Touchscreen.isSupported()){
return false;
}else{
fieldChangeNotify(1);
return true;
}
}
protected boolean touchEvent(TouchEvent message)
{
if (TouchEvent.CLICK == message.getEvent())
{
FieldChangeListener listener = getChangeListener();
if (null != listener)
this.setFocus();
listener.fieldChanged(this, 1);
}
return super.touchEvent(message);
}
}
The issue is here:
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth(), height);
setExtent(Display.getWidth(), height);
}
You're giving manager height less that it needs for content (only image_width).
Also here is possible error:
width=image_width;
height=image_width;
You should use image_height for the height.
And sure you could use scrolling for VerticalManager - add style VERTICAL_SCROLL to constructor. But as user I will find the User Experience (UX) strange in this case.

Custom PopUp to work like tooltip without time out

I need to create a Customised PopUp to work like a ToolTip How can i achieve it
i have worked on a code please check out and tell me where i need improvement
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.PopupScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
public class ToolTip extends PopupScreen{
private static VerticalFieldManager vfm;
private LabelField lbl;
private int xPosition;
private int yPosition;
private String message;
public ToolTip(String message,int xPos,int yPos){
super(vfm);
this.xPosition=xPos;
this.yPosition=yPos;
this.message=message;
vfm=new VerticalFieldManager(){
protected void paint(Graphics graphics) {
graphics.setColor(0x00FFFFFF);
graphics.fillRect(0,0,getWidth(),getHeight());
graphics.setColor(0x00000000);
graphics.drawRect(0,0,getWidth(),getHeight());
super.paint(graphics);
}
};
lbl=new LabelField(message);
vfm.add(lbl);
}
protected void sublayout(int width, int height) {
super.sublayout(width, height);
setExtent(lbl.getPreferredWidth(), lbl.getPreferredHeight());
setPosition(xPosition, yPosition);
}
}
i get an error of NullPointer Exception at super(vfm) because vfm is null when i use it as follows . How can i optimise my code .
ButtonField bf1=new ButtonField("Login"){
protected boolean navigationClick(int status, int time) {
UiApplication.getUiApplication().pushScreen(new ToolTip("Hello ", 50, 50));
return super.navigationClick(status, time);
}
};
add(bf1);
Pass an initialized instance of VerticalFieldManager to super(..) of PopupScreen. Check following code.
class ToolTip extends PopupScreen {
private static VerticalFieldManager vfm = new VerticalFieldManager() {
protected void paint(Graphics graphics) {
graphics.setColor(0x00FFFFFF);
graphics.fillRect(0, 0, getWidth(), getHeight());
graphics.setColor(0x00000000);
graphics.drawRect(0, 0, getWidth(), getHeight());
super.paint(graphics);
}
};
// other codes
public ToolTip(String message, int xPos, int yPos) {
super(vfm);
// other codes
}
protected void sublayout(int width, int height) {
// other codes
}
}
Updated code for custom background support
class ToolTip extends PopupScreen {
private int xPosition;
private int yPosition;
public ToolTip(String message, int xPos, int yPos) {
super(new VerticalFieldManager());
// Define and set background here
// Use - BackgroundFactory.createBitmapBackground(bitmap) for bitmap background
getDelegate().setBackground(BackgroundFactory.createSolidBackground(Color.RED));
// Add other UI Field here
this.xPosition=xPos;
this.yPosition=yPos;
add(new LabelField(message));
// other codes
}
// Empty implementation of this will disable default rounded border.
protected void applyTheme() {
}
protected void sublayout(int width, int height) {
super.sublayout(width, height);
setPosition(xPosition, yPosition);
}
}
You need to use getDelegate().setBackground(..) to set the background. Check the class BackgroundFactory for creating custom background.

How to setBackground of Field in Blackberry 4.5?

I have defined a BitmapButtonField in Blackberry. But the default grey color background does not go. And the Bluish onFocus border?
How to change them in BB 4.5
Hi this is bitmap button and background color Red
manager=new Field(Field.FOCUSABLE){
protected void onFocus(int direction) {
super.onFocus(direction);
flag1=true;
invalidate();
}
protected void onUnfocus() {
flag1=false;
invalidate();
}
protected void layout(int width, int height) {
setExtent(image.getWidth(),image.getHeight());
}
protected void paint(Graphics graphics) {
if(flag1){
graphics.setBackgroundColor(Color.RED);
graphics.clear();
graphics.drawBitmap(0, 0, image.getWidth(),image.getHeight(), image_hover,0,0);
}else{
graphics.drawBitmap(0, 0, image.getWidth(),image.getHeight(), image,0,0);
}
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(1);
return true;
}
};
manager.setChangeListener(this);
add(manager);
output as following image
This is background image and with default background color
manager1=new Field(Field.FOCUSABLE){
protected void onFocus(int direction) {
super.onFocus(direction);
flag2=true;
invalidate();
}
protected void onUnfocus() {
button=image;
flag2=false;
invalidate();
}
protected void layout(int width, int height) {
setExtent(image.getWidth(),image.getHeight());
}
protected void paint(Graphics graphics) {
if(flag2)
graphics.drawBitmap(0, 0, image.getWidth(),image.getHeight(), image_hover,0,0);
else
graphics.drawBitmap(0, 0, image.getWidth(),image.getHeight(), image,0,0);
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(1);
return true;
}
};
manager1.setChangeListener(this);
add(manager1);
out put as following
Fully functional class is following for better understanding
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.container.MainScreen;
public class StartUp extends UiApplication{
public static void main(String[] args) {
StartUp up=new StartUp();
up.enterEventDispatcher();
}
public StartUp()
{
pushScreen(new Demoscreen());
}
class Demoscreen extends MainScreen implements FieldChangeListener
{
Bitmap image,image_hover;
boolean flag1,flag2;
Field manager=null,manager1=null;
public Demoscreen() {
image=Bitmap.getBitmapResource("Download_48x48.png");
image_hover=Bitmap.getBitmapResource("Download_48x48.png");
manager=new Field(Field.FOCUSABLE){
protected void onFocus(int direction) {
super.onFocus(direction);
flag1=true;
invalidate();
}
protected void onUnfocus() {
flag1=false;
invalidate();
}
protected void layout(int width, int height) {
setExtent(image.getWidth(),image.getHeight());
}
protected void paint(Graphics graphics) {
if(flag1){
graphics.setBackgroundColor(Color.RED);
graphics.clear();
graphics.drawBitmap(0, 0, image.getWidth(),image.getHeight(), image_hover,0,0);
}else{
graphics.drawBitmap(0, 0, image.getWidth(),image.getHeight(), image,0,0);
}
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(1);
return true;
}
};
manager.setChangeListener(this);
add(manager);
manager1=new Field(Field.FOCUSABLE){
protected void onFocus(int direction) {
super.onFocus(direction);
flag2=true;
invalidate();
}
protected void onUnfocus() {
flag2=false;
invalidate();
}
protected void layout(int width, int height) {
setExtent(image.getWidth(),image.getHeight());
}
protected void paint(Graphics graphics) {
if(flag2)
graphics.drawBitmap(0, 0, image.getWidth(),image.getHeight(), image_hover,0,0);
else
graphics.drawBitmap(0, 0, image.getWidth(),image.getHeight(), image,0,0);
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(1);
return true;
}
};
manager1.setChangeListener(this);
add(manager1);
}
public void fieldChanged(Field field, int context) {
if(field==manager)
{
displayDialog("I am first field");
}else if(field==manager1)
{
displayDialog("I am second field");
}
}
public void displayDialog(final String message)
{
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.inform(message);
}
});
}
}
}
For more details please visit following link for BackgroundsBackground logic for 4.5 OS
Check following links for customized Button Field:
Implement advanced buttons, fields, and managers.
User Defined Buttons - Create a Custom Button From an Image
Blackberry Custom Button Field
How to create a Custom Button Field in Blackberry
Normally overriding applyTheme(..) (an empty implementation) removes default styling of a field. Also we need to override paint(..), paintBackground(..), drawFocus(..) and change their implementation according to current focus status of the field. Below is a code snippet for the case when I extend a Field for making Custom Button Field.
private final Bitmap focusedBitMap = Bitmap.getBitmapResource("focused.png");
private final Bitmap unfocusedBitmap = Bitmap.getBitmapResource("unfocused.png");
protected void paint(Graphics graphics) {
// paint background
graphics.setBackgroundColor(isFocus() ? Color.RED : Color.GREEN);
graphics.clear();
// draw button image
Bitmap myBitmap = isFocus() ? focusedBitMap : unfocusedBitmap;
if (myBitmap != null) {
// image position calculation
int imageX = 0;
int imageY = 0;
graphics.drawBitmap(imageX, imageY,
myBitmap.getWidth(), myBitmap.getHeight(),
myBitmap, 0, 0);
}
}
protected void drawFocus(Graphics graphics, boolean on) {
}
public boolean isFocusable() {
return true;
}

Blackberry: custom ButtonField with disappearing focus highlight

I'm trying to create a custom ButtonField, whose focus (the blue highlight color) would disappear after few seconds of inactivity - like in original music player on BB phones with touchscreen.
I've almost succeeded in that with the following example:
Here are the east.png and west.png (courtesy of openclipart.org):
Here is my test code MyFocus.java:
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.image.*;
public class MyFocus extends UiApplication {
public static void main(String[] args) {
MyFocus app = new MyFocus();
app.enterEventDispatcher();
}
public MyFocus() {
pushScreen(new MyScreen());
}
}
class MyScreen extends MainScreen {
public MyScreen() {
setTitle("2nd trackpad click not working");
getMainManager().setBackground(BackgroundFactory.createLinearGradientBackground(Color.WHITE, Color.GRAY, Color.DARKGRAY, Color.GRAY));
add(new MyButton(MyButton.EAST));
add(new MyButton(MyButton.WEST));
add(NF);
}
class MyButton extends ButtonField {
public final static int EAST = 0;
public final static int WEST = 1;
public final static int WIDTH = 100;
public final static int HEIGHT = 100;
private final XYEdges EDGES = new XYEdges(0, 0, 0, 0);
private final Application _app = UiApplication.getUiApplication();
private final static long FOCUS_DURATION = 3000L;
private int _focusTimer = -1;
private final int _direction;
public MyButton(int direction) {
setMargin(EDGES);
setPadding(EDGES);
setImageSize(WIDTH, HEIGHT);
setBorder(VISUAL_STATE_NORMAL,
BorderFactory.createSimpleBorder(EDGES));
setBorder(VISUAL_STATE_FOCUS, BorderFactory.createSimpleBorder(EDGES));
setBorder(VISUAL_STATE_ACTIVE, BorderFactory.createSimpleBorder(EDGES));
setBackground(VISUAL_STATE_NORMAL, BackgroundFactory.createSolidTransparentBackground(Color.GREEN, 0));
setBackground(VISUAL_STATE_FOCUS, BackgroundFactory.createSolidTransparentBackground(Color.BLUE, 100));
setBackground(VISUAL_STATE_ACTIVE, BackgroundFactory.createSolidTransparentBackground(Color.RED, 200));
_direction = direction;
switch(_direction) {
case EAST:
setImage(ImageFactory.createImage("east.png"));
break;
case WEST:
setImage(ImageFactory.createImage("west.png"));
break;
}
}
// display red background on long touch and hold
protected boolean touchEvent(TouchEvent event) {
if (event.getEvent() == TouchEvent.CLICK) {
applyThemeOnStateChange();
return true;
}
return super.touchEvent(event);
}
protected void onUnfocus() {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
super.onUnfocus();
}
protected void onFocus(int direction) {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
_focusTimer = _app.invokeLater(new Runnable() {
public void run() {
MyButton.super.onUnfocus();
_focusTimer = -1;
}
}, FOCUS_DURATION, false);
super.onFocus(direction);
}
public int getPreferredHeight(){
return HEIGHT;
}
public int getPreferredWidth(){
return WIDTH;
}
protected void layout(int width, int height) {
setExtent(WIDTH, HEIGHT);
}
}
}
My problem is visible, when I first select a button and wait few seconds for its focus to disappear. Then I click on the track pad and while the button is pushed (verified that), you don't see anything at the screen - it doesn't turn blue or red.
I've tried all combinations of navigationClick() and trackwheelUnclick() but can not fix that.
Any help please?
Alex
UPDATE 1:
I've tried the following, but it doesn't work well (focus disappears forever, probably because button thinks it is in the needed visual state already):
protected void onFocus(int direction) {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
_focusTimer = _app.invokeLater(new Runnable() {
public void run() {
MyButton.this.setBorder(BorderFactory.createSimpleBorder(EDGES));
MyButton.this.setBackground(BackgroundFactory.createSolidTransparentBackground(Color.GREEN, 0));
invalidate();
_focusTimer = -1;
}
}, FOCUS_DURATION, false);
super.onFocus(direction);
}
UPDATE 2:
A try with a NullField, still not working properly:
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.image.*;
public class MyFocus extends UiApplication {
public static void main(String[] args) {
MyFocus app = new MyFocus();
app.enterEventDispatcher();
}
public MyFocus() {
pushScreen(new MyScreen());
}
}
class MyScreen extends MainScreen {
static NullField NF = new NullField();
HorizontalFieldManager hfm = new HorizontalFieldManager() {
int lastFocused = -1;
protected int firstFocus(int direction) {
lastFocused = super.firstFocus(direction);
System.out.println("XXX firstFocus: " + lastFocused);
return lastFocused;
}
protected int nextFocus(final int direction, final int axis) {
if (getFieldWithFocus() == NF) {
return lastFocused;
}
lastFocused = super.nextFocus(direction, axis);
System.out.println("XXX nextFocus: " + lastFocused);
return lastFocused;
}
};
public MyScreen() {
setTitle("2nd trackpad click not working");
getMainManager().setBackground(BackgroundFactory.createLinearGradientBackground(Color.WHITE, Color.GRAY, Color.DARKGRAY, Color.GRAY));
hfm.add(new MyButton(MyButton.WEST));
hfm.add(new MyButton(MyButton.EAST));
hfm.add(new MyButton(MyButton.EAST));
hfm.add(NF);
add(hfm);
}
class MyButton extends ButtonField {
public final static int EAST = 0;
public final static int WEST = 1;
public final static int WIDTH = 100;
public final static int HEIGHT = 100;
private final XYEdges EDGES = new XYEdges(0, 0, 0, 0);
private final Application _app = UiApplication.getUiApplication();
private final static long FOCUS_DURATION = 3000L;
private int _focusTimer = -1;
private final int _direction;
public MyButton(int direction) {
setMargin(EDGES);
setPadding(EDGES);
setImageSize(WIDTH, HEIGHT);
setBorder(VISUAL_STATE_NORMAL, BorderFactory.createSimpleBorder(EDGES));
setBorder(VISUAL_STATE_FOCUS, BorderFactory.createSimpleBorder(EDGES));
setBorder(VISUAL_STATE_ACTIVE, BorderFactory.createSimpleBorder(EDGES));
setBackground(VISUAL_STATE_NORMAL, BackgroundFactory.createSolidTransparentBackground(Color.GREEN, 0));
setBackground(VISUAL_STATE_FOCUS, BackgroundFactory.createSolidTransparentBackground(Color.BLUE, 100));
setBackground(VISUAL_STATE_ACTIVE, BackgroundFactory.createSolidTransparentBackground(Color.RED, 200));
_direction = direction;
switch(_direction) {
case EAST:
setImage(ImageFactory.createImage("east.png"));
break;
case WEST:
setImage(ImageFactory.createImage("west.png"));
break;
}
}
protected boolean touchEvent(TouchEvent event) {
if (event.getEvent() == TouchEvent.CLICK) {
applyThemeOnStateChange();
return true;
}
return super.touchEvent(event);
}
protected void onUnfocus() {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
super.onUnfocus();
}
protected void onFocus(int direction) {
if (_focusTimer != -1) {
_app.cancelInvokeLater(_focusTimer);
_focusTimer = -1;
}
_focusTimer = _app.invokeLater(new Runnable() {
public void run() {
MyScreen.NF.setFocus();
_focusTimer = -1;
}
}, FOCUS_DURATION, false);
super.onFocus(direction);
}
public int getPreferredHeight(){
return HEIGHT;
}
public int getPreferredWidth(){
return WIDTH;
}
protected void layout(int width, int height) {
setExtent(WIDTH, HEIGHT);
}
}
}
I would probably ovverride the drawFocus() method to check a flag _showFocus before calling super.drawFocus(), then in onFocus(), set the flag to true and schedule the Runnable to change the _showFocus flag to false and invalidate (also setting it to false in onUnfocus()). Don't have to worry about canceling timers or anything this way either, as it is just going to change a flag and invalidate, keeping it in the appropriate state.

How to highlight button when get focus on it in blackberry?

I want to make a blackberry button with images, the one image should be shown when focused and another when unfocused.
or even you can say a blue color when focus is off(by default) and red color when focus is on, how can I achieve such thing ?
see my custom class
import net.rim.device.api.system.Bitmap;
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.FontFamily;
import net.rim.device.api.ui.Graphics;
public class MyButtonField extends Field {
// private int backgroundColour = 0xFFFFFF;
private Bitmap button;
private Bitmap on; //= Bitmap.getBitmapResource("img/pink_scribble.bmp");
private Bitmap off; // = Bitmap.getBitmapResource("img/blue_scribble.bmp");
private int fieldWidth;
private int fieldHeight;
// private int buffer = (Display.getHeight() - 105) / 2;
private String text;
private Font fieldFont;
private boolean btn_text = true;
private static long style = Field.FIELD_HCENTER | Field.FIELD_VCENTER;
public MyButtonField(String _text, String onpath, String offpath) {
super(Field.FOCUSABLE | style);
text = _text;
on = Bitmap.getBitmapResource(onpath);
off = Bitmap.getBitmapResource(offpath);
fieldWidth = on.getWidth();
fieldHeight = on.getHeight();
button = off;
fieldFont = FieldFont();
}
public MyButtonField(String _text, String onpath, String offpath, String focusedpath){
this(_text, onpath, offpath);
}
public MyButtonField(String _text, String onpath, String offpath, boolean btn_text) {
this(_text, onpath , offpath);
this.btn_text = btn_text;
}
public MyButtonField(String _text, String onpath, String offpath, boolean btn_text, int style, int size)
{
this(_text, onpath , offpath, btn_text);
fieldFont = FieldFont(style, size);
}
public MyButtonField(String _text, String onpath, String offpath, long style)
{
this(_text, onpath , offpath);
}
// public MyButtonField(String _text, String onpath, String offpath, int background)
// {
// this(_text, onpath , offpath);
//// backgroundColour = background;
// }
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(1);
return true;
}
protected void onFocus(int direction) {
button = on;
invalidate();
}
protected void onUnfocus() {
button = off;
invalidate();
}
public int getPreferredWidth() {
return fieldWidth;
}
public int getPreferredHeight() {
return fieldHeight;
}
protected void layout(int arg0, int arg1) {
setExtent(getPreferredWidth(), getPreferredHeight());
}
public static Font FieldFont()
{
try {
FontFamily theFam = FontFamily.forName("SYSTEM");
return theFam.getFont(net.rim.device.api.ui.Font.PLAIN, 14);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
public static Font FieldFont(int style, int size)
{
try {
FontFamily theFam = FontFamily.forName("SYSTEM");
return theFam.getFont(style, size);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
protected void drawFocus(Graphics graphics, boolean on) {
if (on) {
//graphics.setColor(Color.RED);
int width = getWidth();
int height = getHeight();
graphics.drawBitmap(0, 0, fieldWidth, fieldHeight, button, 0, 0);
//Draw a border around the field.
/*
graphics.fillRoundRect(0, 0, 3, height,10,10); //Left border
graphics.fillRoundRect(0, 0, width, 3,10,10); //Top border
graphics.fillRoundRect(width-3, 0, 3, height,10,10); //Right border
graphics.fillRoundRect(0, height-3, width, 3,10,10); //Bottom border
*/
graphics.setColor(Color.GRAY);
}
invalidate();
}
public void setFocusImage()
{
button = on;
}
public void setUnFocusImage()
{
button = off;
}
protected void fieldChangeNotify(int context) {
this.getChangeListener().fieldChanged(this, context);
}
protected void paint(Graphics graphics)
{
graphics.drawBitmap(0, 0, fieldWidth, fieldHeight, button, 0, 0);
graphics.setFont(getFont().derive(Font.PLAIN, 8));
graphics.setColor(Color.LIGHTGRAY);
// graphics.fillRoundRect(0, 0, fieldWidth, fieldHeight, 8, 8);
// graphics.setColor(Color.GRAY);
//graphics.drawRoundRect(0, 0, fieldWidth, fieldHeight, 8, 8);
if(btn_text)
graphics.drawText(text, 10, 5);
}
public String getLabel() {
return text;
}
}
You should override onFocus(), onUnfocus() and paint().
Please refer to Custom Button Field article.
You are probably missing this point:
public boolean isFocusable() {
return true;
}
This should be in your custom Field in order the BB UI framework to understand it is a focusable field. Yes, this is odd, since you're already passing Field.FOCUSABLE in constructor, however just give it a try.
Why are you overriding drawFocus() method. Since you are overriding paint method and onFocus & onUnFocus to change bitmap, you don't need to do anything in drawFocus(). Use paint method to draw anything. Everytime you call Invalide(), it will ask screen/field to repaint itself. So remove all code from drawFocus and add it in paint method.
protected void drawFocus(Graphics graphics, boolean on)
{
// Do nothing
}
protected void paint(Graphics graphics)
{
graphics.drawBitmap(0, 0, fieldWidth, fieldHeight, button, 0, 0);
graphics.setFont(getFont().derive(Font.PLAIN, 8));
graphics.setColor(Color.LIGHTGRAY);
if(btn_text)
graphics.drawText(text, 10, 5);
}
Hope it solves your problem.

Resources