Blackberry Custom ButtonField - blackberry

This is default look when i launch activity.
After i play around with the wheel track pad then become like this. The button image or whole button lost.
Here is my custom buttonfield which extends ButtonField.
public class Custom_ButtonField extends ButtonField {
Bitmap mNormal;
Bitmap mFocused;
Bitmap mActive;
int mWidth;
int mHeight;
public Custom_ButtonField(Bitmap normal, Bitmap focused,
Bitmap active) {
super(CONSUME_CLICK);
mNormal = normal;
mFocused = focused;
mActive = active;
mWidth = mNormal.getWidth();
mHeight = mNormal.getHeight();
setMargin(0, 0, 0, 0);
setPadding(0, 0, 0, 0);
setBorder(BorderFactory
.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
setBorder(VISUAL_STATE_ACTIVE, BorderFactory
.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
}
protected void paint(Graphics graphics) {
Bitmap bitmap = null;
switch (getVisualState()) {
case VISUAL_STATE_NORMAL:
bitmap = mNormal;
break;
case VISUAL_STATE_FOCUS:
bitmap = mFocused;
break;
case VISUAL_STATE_ACTIVE:
bitmap = mActive;
break;
default:
bitmap = mNormal;
}
graphics.drawBitmap(0, 0, bitmap.getWidth(), bitmap.getHeight(),
bitmap, 0, 0);
}
public int getPreferredWidth() {
return mWidth;
}
public int getPreferredHeight() {
return mHeight;
}
protected void layout(int width, int height) {
setExtent(mWidth, mHeight);
}
}

It looks like you're trying to create a button with an image so you might be better off using the Advanced UI Library published by RIM. Take a look at the BitmapButtonField class.

Set Focusable on constructor.
super(Field.FOCUSABLE);

Related

Label caption is not set in label background center

I am working on a logic where I have to align the label caption in vertically center but it's not working.
I have tried to set text padding but the whole label with background is shifting.Is there any way to solve this.
Here is my code:
final Bitmap tabBackGroundImage1 = Bitmap.getBitmapResource("box_img.png");
homeContentManager.setBorder( BorderFactory.createBitmapBorder(
new XYEdges(16,16,16,16), tabBackGroundImage));
//homeContentManager.setBorder(roundedBourder);
//HOME SCREEN HORIZONTAL MANAGER
buddiesLabel=new LabelField("Buddies");
_bitmap = EncodedImage.getEncodedImageResource("buddies.png");
final BitmapField buddiesBmp = new BitmapField(Constant.sizePic(_bitmap,
_bitmap.getHeight(), _bitmap.getWidth()));
buddiesBmp.setMargin(3,5,0,5);
if(BuddyListField.onlineBuddyCount < 1000) {
buddyCount=new LabelField(" "+BuddyListField.onlineBuddyCount+" "){
/*public void setText(String text,int offset,int length){
text = String.valueOf(BuddyListField.onlineBuddyCount);
offset = 200;
length = 5;
super.setText(text, offset, length);
}*/
public int getPreferredHeight() {
return tabBackGroundImage1.getHeight();
}
public int getPreferredWidth() {
return tabBackGroundImage1.getWidth();
}
protected void layout(int width, int height) {
super.layout(width, height);
setExtent(Math.min(width, tabBackGroundImage1.getWidth()), Math.min(height, tabBackGroundImage1.getHeight()));
}
protected void paint(Graphics graphics) {
int deviceWidth=net.rim.device.api.system.Display.getWidth();
int deviceHeight=net.rim.device.api.system.Display.getHeight();
graphics.clear();
graphics.drawBitmap(0, 0, deviceWidth,
deviceHeight, tabBackGroundImage1, 0, 0);
super.paint(graphics);
}
};
This is the output:
But I need to set zero to vertically center in background.
Try like this
protected void paint(Graphics graphics) {
int deviceWidth=net.rim.device.api.system.Display.getWidth();
int deviceHeight=net.rim.device.api.system.Display.getHeight();
graphics.clear();
graphics.drawBitmap(0, 0, deviceWidth,
deviceHeight, tabBackGroundImage1, 0, 0);
graphics.drawText((getPreferredWidth()-getText())/2,(getPreferredHeight()-graphics.getFont().getHeight())/2,getText);
// super.paint(graphics);
}

How to detect whether field is touched or clicked?

I override the method like this.
newsbtn = new Custom_ButtonField(news, newsactive, newsactive) {
protected boolean navigationClick(int status, int time) {
Main.getUiApplication().pushScreen(
new Menu_PopupMenu(position));
return true;
}
protected boolean touchEvent(TouchEvent message) {
int eventCode = message.getEvent();
if (eventCode == TouchEvent.UNCLICK){
Main.getUiApplication().pushScreen(
new Menu_PopupMenu(position));
}
return true;
}
};
add(newsbtn);
Here is the Custom_ButtonField
public class Custom_ButtonField extends ButtonField {
Bitmap mNormal;
Bitmap mFocused;
Bitmap mActive;
int mWidth;
int mHeight;
private int color = -1;
String text;
public Custom_ButtonField(Bitmap normal, Bitmap focused, Bitmap active) {
super(CONSUME_CLICK | Field.FOCUSABLE | Field.FIELD_HCENTER
| Field.FIELD_VCENTER);
mNormal = normal;
mFocused = focused;
mActive = active;
mWidth = mNormal.getWidth();
mHeight = mNormal.getHeight();
setMargin(0, 0, 0, 0);
setPadding(0, 0, 0, 0);
setBorder(BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
setBorder(VISUAL_STATE_ACTIVE,
BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
}
public Custom_ButtonField(String text, Bitmap normal, Bitmap focused,
Bitmap active, int color) {
super(CONSUME_CLICK | Field.FOCUSABLE | Field.FIELD_HCENTER
| Field.FIELD_VCENTER);
this.color = color;
mNormal = normal;
mFocused = focused;
mActive = active;
mWidth = mNormal.getWidth();
mHeight = mNormal.getHeight();
setMargin(0, 0, 0, 0);
setPadding(0, 0, 0, 0);
setBorder(BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
setBorder(VISUAL_STATE_ACTIVE,
BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
this.text = text;
}
public Custom_ButtonField(String text, Bitmap normal, Bitmap focused,
Bitmap active, int color, long style) {
super(style);
this.color = color;
mNormal = normal;
mFocused = focused;
mActive = active;
mWidth = mNormal.getWidth();
mHeight = mNormal.getHeight();
setMargin(0, 0, 0, 0);
setPadding(0, 0, 0, 0);
setBorder(BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
setBorder(VISUAL_STATE_ACTIVE,
BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
this.text = text;
}
public void setText(String text){
this.text = text;
invalidate();
}
public String getText(){
return text;
}
public void setColor(int color){
this.color = color;
}
protected void onFocus(int direction) {
super.onFocus(direction);
color = 0x540604;
this.invalidate();
}
protected void onUnfocus() {
super.onUnfocus();
color = Color.WHITE;
this.invalidate();
}
protected void paint(Graphics graphics) {
int fontcontent;
if (Display.getWidth() > 480)
fontcontent = 28;
else if (Display.getWidth() < 481 && Display.getWidth() > 320)
fontcontent = 23;
else
fontcontent = 18;
Bitmap bitmap = null;
switch (getVisualState()) {
case VISUAL_STATE_NORMAL:
bitmap = mNormal;
break;
case VISUAL_STATE_FOCUS:
bitmap = mFocused;
break;
case VISUAL_STATE_ACTIVE:
bitmap = mActive;
break;
default:
bitmap = mNormal;
}
setBackground(BackgroundFactory.createBitmapBackground(bitmap));
graphics.setFont(Font.getDefault().derive(Font.PLAIN, fontcontent));
graphics.setColor(color);
graphics.drawText(text, (mNormal.getWidth() - Font.getDefault()
.getAdvance(text)) / 2, ((mNormal.getHeight() - Font
.getDefault().getHeight()) / 2) + 10, DrawStyle.HCENTER
| DrawStyle.VCENTER);
}
public int getPreferredWidth() {
return mWidth;
}
public int getPreferredHeight() {
return mHeight;
}
protected void layout(int width, int height) {
setExtent(mWidth, mHeight);
}
}
However, the button unable to perform push screen and only setfocus() on the button.
You don't have to use the CONSUME_CLICK constructor field, just to get clicks. That determines whether or not the field consumes click events, or lets them propagate to other classes to handle. But, the poster's code is already returning true in his two click handling methods, which also means "I've already handled this click ... don't bother passing it to other Field classes". See more on this here
And as Alan said in his comment, he was already using CONSUME_CLICK, so that's definitely not the problem.
If the Custom_ButtonField class is the same one you posted here, then I am able to get clicks just fine when I use your code. However, there's one potential problem I could see. You don't show your Java imports. Does your TouchEvent import look like this?
import net.rim.device.api.ui.TouchEvent;
There's actually another TouchEvent class in the BlackBerry frameworks, and if you used the wrong one, then you've created a method that doesn't actually override the base class touchEvent(). It's easy to use the Eclipse shortcut to put in your imports, but it's possible to get the wrong one.
I think if you do this, though, Eclipse should show a warning that the incorrect version of touchEvent() is never called.
Edit: by the way, I usually trigger my click handling code on the TouchEvent.UNCLICK event, not on TouchEvent.CLICK. I think that makes for a better UI. The click doesn't register until the user's finger has been lifted. But, that's a minor thing, and isn't the reason for this problem.
What is the parent of your Custom_ButtonField ?
If it is a buttonField, you have to set the attribute CONSUME_CLICK in the constructor

Image gone After Focusing

This is before focus state. It work fine.
This is on focusing state. It work fine.
This is after focus state. It occurred problem where the image gone.
It works fine for the top right but top left image got problem.
Here is my custom VerticalFieldManager:
public class Custom_TopField extends HorizontalFieldManager implements
FieldChangeListener {
private Bitmap bg = Bitmap.getBitmapResource("header_bar.png");
private Bitmap download = Bitmap.getBitmapResource("btn_download.png");
private Bitmap downloadactive = Bitmap
.getBitmapResource("btn_download_active.png");
private Bitmap refresh = Bitmap.getBitmapResource("icon_refresh.png");
private Bitmap refreshactive = Bitmap
.getBitmapResource("icon_refresh_active.png");
private Bitmap back = Bitmap.getBitmapResource("btn_back.png");
private Bitmap backctive = Bitmap.getBitmapResource("btn_back_active.png");
private Bitmap news = Bitmap.getBitmapResource("icon_news.png");
private Bitmap newsactive = Bitmap
.getBitmapResource("icon_news_active.png");
private Custom_ButtonField downloadbtn, refreshbtn, backbtn, newsbtn;
private Custom_LabelField title;
Custom_TopField(final MainScreen mainscreen) {
Background background = BackgroundFactory.createBitmapBackground(bg);
setBackground(background);
title = new Custom_LabelField("东方日报", DrawStyle.ELLIPSIS
| LabelField.USE_ALL_WIDTH | DrawStyle.HCENTER
| Field.FOCUSABLE, Color.WHITE) {
protected boolean navigationClick(int status, int time) {
Main.getUiApplication().pushScreen(new Main_AllLatestNews());
Main.getUiApplication().popScreen(mainscreen);
return true;
}
};
title.setFont(Font.getDefault().derive(Font.BOLD, 33));
add(title);
downloadbtn = new Custom_ButtonField(download, downloadactive,
downloadactive);
downloadbtn.setChangeListener(this);
add(downloadbtn);
refreshbtn = new Custom_ButtonField(refresh, refreshactive,
refreshactive);
refreshbtn.setChangeListener(this);
add(refreshbtn);
backbtn = new Custom_ButtonField(back, backctive, backctive);
backbtn.setChangeListener(this);
add(backbtn);
/*newsbtn = new Custom_ButtonField(news, newsactive, newsactive);
newsbtn.setChangeListener(this);
add(newsbtn);*/
}
protected void sublayout(int width, int height) {
Field field = getField(0);
layoutChild(field, 120, Font.getDefault().getHeight());
setPositionChild(field, (getPreferredWidth() - title.getWidth()) / 2,
15);
field = getField(1);
layoutChild(field, download.getWidth(), download.getHeight());
setPositionChild(field, getPreferredWidth()
- (download.getWidth() + 10),
getPreferredHeight() - (download.getHeight() + 5));
field = getField(2);
layoutChild(field, refresh.getWidth(), refresh.getHeight());
setPositionChild(field,
getPreferredWidth() - (refresh.getWidth() + 10),
getPreferredHeight() - (refresh.getHeight() + 5));
field = getField(3);
layoutChild(field, back.getWidth(), back.getHeight());
setPositionChild(field, 10, 5);
/*field = getField(4);
layoutChild(field, news.getWidth(), news.getHeight());
setPositionChild(field, 10, 5);*/
width = Math.min(width, getPreferredWidth());
height = Math.min(height, getPreferredHeight());
setExtent(width, height);
}
public int getPreferredHeight() {
return 70;
}
public int getPreferredWidth() {
return Display.getWidth();
}
public void paint(Graphics graphics) {
int rectHeight = getPreferredHeight();
int rectWidth = getPreferredWidth();
graphics.drawRect(0, 0, rectWidth, rectHeight);
super.paint(graphics);
}
public void fieldChanged(Field field, int context) {
if (field == downloadbtn) {
} else if (field == refreshbtn) {
} else if (field == backbtn) {
} else if (field == newsbtn) {
}
}
}
Here is custom button field
public class Custom_ButtonField extends ButtonField {
Bitmap mNormal;
Bitmap mFocused;
Bitmap mActive;
int mWidth;
int mHeight;
private int color = -1;
String text;
public Custom_ButtonField(Bitmap normal, Bitmap focused, Bitmap active) {
super(CONSUME_CLICK | Field.FOCUSABLE);
mNormal = normal;
mFocused = focused;
mActive = active;
mWidth = mNormal.getWidth();
mHeight = mNormal.getHeight();
setMargin(0, 0, 0, 0);
setPadding(0, 0, 0, 0);
setBorder(BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
setBorder(VISUAL_STATE_ACTIVE,
BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
}
public Custom_ButtonField(String text, Bitmap normal, Bitmap focused,
Bitmap active, int color) {
super(CONSUME_CLICK | Field.FOCUSABLE);
this.color = color;
mNormal = normal;
mFocused = focused;
mActive = active;
mWidth = mNormal.getWidth();
mHeight = mNormal.getHeight();
setMargin(0, 0, 0, 0);
setPadding(0, 0, 0, 0);
setBorder(BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
setBorder(VISUAL_STATE_ACTIVE,
BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
this.text = text;
}
protected void onFocus(int direction) {
super.onFocus(direction);
}
protected void onUnfocus() {
super.onUnfocus();
}
protected void paint(Graphics graphics) {
Bitmap bitmap = null;
switch (getVisualState()) {
case VISUAL_STATE_NORMAL:
bitmap = mNormal;
break;
case VISUAL_STATE_FOCUS:
bitmap = mFocused;
break;
case VISUAL_STATE_ACTIVE:
bitmap = mActive;
break;
default:
bitmap = mNormal;
}
graphics.drawBitmap(0, 0, bitmap.getWidth(), bitmap.getHeight(),
bitmap, 0, 0);
graphics.setFont(Font.getDefault().derive(Font.BOLD, 25));
graphics.setColor(color);
graphics.drawText(text, (mNormal.getWidth() - Font.getDefault()
.getAdvance(text)) / 2, ((mNormal.getHeight() - Font
.getDefault().getHeight()) / 2) + 10, DrawStyle.HCENTER
| DrawStyle.VCENTER);
}
public int getPreferredWidth() {
return mWidth;
}
public int getPreferredHeight() {
return mHeight;
}
protected void layout(int width, int height) {
setExtent(mWidth, mHeight);
}
}
This is the second problem just like this I've seen in the last couple weeks.
Background
To understand the solution, first you should understand the basic UI classes in BlackBerry.
First, we have the Field class. A Field is the base class of the normal UI components. If you write a UI component yourself, from scratch, then you would subclass Field:
public class MyWidget extends Field {
However, if there already exists a BlackBerry class that does almost what you need, and you just need to change its behaviour a bit, then you would subclass something else. For example:
public class MyButtonWidget extends ButtonField {
The same pattern exists for the Manager class. If you are writing a Manager from scratch, then extend Manager:
public class MyManager extends Manager {
which involves doing this, according to the BlackBerry docs:
Implementing your own layout manager
If you have particular needs, you
can implement your own manager. Extend the Manager class, and
implement sublayout, getPreferredWidth, and getPreferredHeight. For
efficiency, you may optionally override subpaint.
However, if an existing Manager subclass already does most of what you need, and you just want to customize it, then you might consider extending that subclass:
public class MyHorizontalManager extends HorizontalFieldManager {
In your case, your Custom_TopField is doing all of the required work for a fully custom Manager (see the highlighted quote above from the javadocs). So, there's not really any reason for you to extend HorizontalFieldManager. A HorizontalFieldManager is used when you just want to add() your fields, and have them all laid out horizontally. But, you do that explicitly in your sublayout() code. As it turns out, it looks like your logic is competing with the base class.
Solution
So, what you should do, is have your class just extend Manager:
public class Custom_TopField extends Manager implements FieldChangeListener {
If you do that, you will need to call a different super constructor. Something like this (you might want to pick different style constants depending on your needs):
Custom_TopField(final MainScreen mainscreen) {
super(Manager.USE_ALL_WIDTH | Manager.NO_VERTICAL_SCROLL | Manager.NO_HORIZONTAL_SCROLL);
Another alternative would be to simply not implement sublayout(), extend HorizontalFieldManager like you originally had, and then control layout with the child fields' margins and long style flags. But, since the solution I gave above requires only changing 2 lines of code, that's probably the easiest for you this time.
Other Problem(s)
I also noticed in your code, and screenshots, that the Download button doesn't show up. I don't know the exact size of all your png images, but if the refresh and download images are the same size, then your current logic is just laying out the refresh button right over the download button. So, the download button is hidden. That's probably not what you want?

How i cn set Backgroungd image in Blackberry?

i want to set background image in Vertical field manager. i had try but it not fill with height you can see that in my screen. and Following in my code what i am doing mistake please help me.
vfmCenter = new VerticalFieldManager(FIELD_HCENTER)
{
public void paint(Graphics graphics)
{
graphics.clear();
graphics.drawBitmap(0, 0,deviceWidth,deviceHeight,newimg,0,0);
super.paint(graphics);
}
protected void sublayout( int maxWidth, int maxHeight)
{
int width = Display.getWidth();
int height = Display.getHeight();
super.sublayout( width, height);
setExtent( width, height);
}
};
vfmMain.add(vfmCenter);
this.add(vfmMain);
I was also facing the same issue earlier.. I solved my problem with this..
class MyClass extends MainScreen
{
// function for scaling your image to fit the screen
public EncodedImage scaleImage(EncodedImage source, int requiredWidth, int requiredHeight)
{
int currentWidthFixed32 = Fixed32.toFP(source.getWidth());
int requiredWidthFixed32 = Fixed32.toFP(requiredWidth);
int scaleXFixed32 = Fixed32.div(currentWidthFixed32, requiredWidthFixed32);
int currentHeightFixed32 = Fixed32.toFP(source.getHeight());
int requiredHeightFixed32 = Fixed32.toFP(requiredHeight);
int scaleYFixed32 = Fixed32.div(currentHeightFixed32, requiredHeightFixed32);
return source.scaleImage32(scaleXFixed32, scaleYFixed32);
}
public MyClass
{
ei = EncodedImage.getEncodedImageResource("res/background_image");
ei1= scaleImage(ei,requires_width,required_height);
vfm= new VerticalFieldManager(VerticalFieldManager.USE_ALL_HEIGHT|VerticalFieldManager.USE_ALL_WIDTH);
vfm.setBackground(BackgroundFactory.createBitmapBackground(ei1.getBitmap()));
vfm.add(new LabelField("hello notice the background behind me");
add(vfm);
}
}
Try this. I think it will work for you!!
Try like this:
VerticalFieldManager vertical=new VerticalFieldManager()
{
protected void paint(Graphics g)
{
g.drawBitmap(0, 0,Display.getWidth(), Display.getHeight(), bitmap, 0, 0);
super.paint(g);
}
protected void sublayout(int maxWidth, int maxHeight)
{
super.sublayout(Display.getWidth(),Display.getHeight());
setExtent(Display.getWidth(),Display.getHeight());
}
};
add(vertical);
you can get.
This is the simple using getMainManager but whole background not a particular Field Manager
getMainManager().setBackground(BackgroundFactory.createBitmapBackground(Bitmap.getBitmapResource("sample.png")));

BlackBerry 6.0 bitmap background using paintBackground issues with scrolling

I'm having a very strange problem with a background behind a VerticalFieldManager.
I have a Manager (NO_VERTICAL_SCROLL | NO_HORIZONTAL_SCROLL) that draws the background in paintBackground method which has 1 child:
VerticalFieldManager(VERTICAL_SCROLL | VERTICAL_SCROLLBAR) which stores the fields that need to be scrolled.
When the VerticalFieldManager scrolls the Manager background starts moving (and its choppy). When I use the setBackground to set the background image everything works fine, but I need the support of 4.5+. Anyone experienced this before?
my screen class:
public class RMainScreen extends MainScreen {
EncodedImage fon = EncodedImage.getEncodedImageResource("background_480x360.png");
HorizontalFieldManager content;
public RMainScreen() {
super(USE_ALL_WIDTH | USE_ALL_HEIGHT | NO_VERTICAL_SCROLL | NO_VERTICAL_SCROLLBAR);
content = new HorizontalFieldManager(HorizontalFieldManager.USE_ALL_WIDTH | HorizontalFieldManager.NO_VERTICAL_SCROLL | HorizontalFieldManager.NO_VERTICAL_SCROLLBAR) {
protected void paintBackground(Graphics g) {
g.drawImage(0, 0, fon.getWidth(), fon.getHeight(), fon, 0, getLeft(), getTop());
}
};
VerticalFieldManager list = new VerticalFieldManager(VerticalFieldManager.USE_ALL_WIDTH | VerticalFieldManager.VERTICAL_SCROLL | VerticalFieldManager.VERTICAL_SCROLLBAR);
for(int i=0; i<40; i++) {
list.add(new LabelField("item from list " + i, LabelField.FOCUSABLE) {
protected void paint(Graphics g) {
g.setColor(Color.WHITE);
super.paint(g);
}
});
}
content.add(list);
add(content);
}
}
Try this one, use this code in your class constructor.
Bitmap topBg = Bitmap.getBitmapResource(ImageName.topbar);
final Bitmap topBg1 = resizeBitmap(topBg, SCREEN_WIDTH, topBg.getHeight());
VerticalFieldManager vfmTop = new VerticalFieldManager(Field.USE_ALL_WIDTH | USE_ALL_WIDTH)
{
protected void paintBackground(Graphics graphics)
{
graphics.drawBitmap(0,0,SCREEN_WIDTH,topBg1.getHeight(), topBg1,0,0 );
super.paint(graphics);
}
protected void sublayout(int maxWidth, int maxHeight) {
// TODO Auto-generated method stub
super.sublayout(topBg1.getWidth(), topBg1.getHeight());
setExtent(topBg1.getWidth(), topBg1.getHeight());
}
};
public static Bitmap resizeBitmap(Bitmap image, int width, int height)
{
int rgb[] = new int[image.getWidth() * image.getHeight()];
image.getARGB(rgb, 0, image.getWidth(), 0, 0, image.getWidth(), image.getHeight());
int rgb2[] = rescaleArray(rgb, image.getWidth(), image.getHeight(), width, height);
Bitmap temp2 = new Bitmap(width, height);
temp2.setARGB(rgb2, 0, width, 0, 0, width, height);
return temp2;
}

Resources