I'd like to create an Image Button that has three states:
Normal
Focused
Pressed (or "down" or "active" whatever you call it)
Normal and Focused is pretty straightforward. I used the well-known classes BaseButtonField and BitmapButtonField as a bases. My Problem is that
protected boolean trackwheelClick(int status, int time)
is not called. My Button extends from Field and has Field.FOCUSABLE | Field.EDITABLE as styles. What am I missing?
You can try with "Tutorial: Creating a custom button" of the official RIM docs.
I think it is what your looking for
The below code is a custom button field for bottom menu bar. This will be useful for your task.
public class PictureBackgroundButtonField extends BitmapField {
MyTooltip _tooltip;
Bitmap mNormal;
Bitmap mFocused;
Bitmap mActive;
String text;
int mWidth;
int mHeight;
int xpos1;
public PictureBackgroundButtonField(String text,Bitmap normal, Bitmap focused, int xpos)
{
super(normal,FOCUSABLE);
mNormal = normal;
mFocused = focused;
mWidth = mNormal.getWidth();
mHeight = mNormal.getHeight();
this.text=text;
setMargin(0, 0, 0, 0);
setPadding(0, 0, 0, 0);
xpos1 = xpos;
}
public String getText()
{
return text;
}
public void setText(String text)
{
this.text=text;
}
protected void paint(Graphics graphics) {
Bitmap bitmap = mNormal;
if(isFocus())
{
bitmap = mFocused;
}
else
{
bitmap = mNormal;
}
graphics.drawBitmap(0, 0, bitmap.getWidth(), bitmap.getHeight(), bitmap, 0, 0);
}
protected void drawFocus(Graphics graphics, boolean on) {
}
protected void onFocus(int direction) {
//lbt.setText(text);
invalidate();
super.onFocus(direction);
if ( _tooltip != null ) {
_tooltip.removeToolTip();
_tooltip = null;
}
// Display tooltip at 50,50 for 5 seconds
_tooltip = MyTooltip.addToolTip(UiApplication.getUiApplication(), text, xpos1, 270, 1);
}
protected void onUnfocus() {
//lbt.setText("");
invalidate();
super.onUnfocus();
if ( _tooltip != null ) {
// We have displayed a Tooltip - remove it
_tooltip.removeToolTip();
_tooltip = null;
}
}
public int getPreferredWidth() {
return mWidth;
}
public int getPreferredHeight() {
return mHeight;
}
protected void layout(int width, int height) {
setExtent(mWidth, mHeight);
}
}
When a field is in the 'active' or 'pressed' state its visual state is set to Field.VISUAL_STATE_ACTIVE. If you check for this in your paint() method by calling Field.getVisualState() you'll be able to change how your button is displayed when it's pressed.
Related
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.
Hi developers I have a screen with transparent background(bitmap). I have a list field placed on top of it, but the issue is the transparent background is not showing the previous screen, instead it shows white screen with listfield.
public class IndexScreen extends MainScreen implements ListFieldCallback {
private Vector rows;
ListField listItems;
int listItem;
int listFieldIndex = -1;
TableRowManager row;
Bitmap indexBox = Bitmap.getBitmapResource("res/screens/Index_Box.png");
public IndexScreen() {
listItems = new ListField() {
listItems.setRowHeight(20);
listItems.setCallback(this);
rows = new Vector();
listItems.setSize(rows.size());
_listVfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL) {
public void paint(Graphics g) {
g.drawBitmap(0, 0, UIinitialize.screenWidth,
UIinitialize.screenHeight, indexBox, 0, 0);
super.paint(g);
}
protected boolean navigationMovement(int dx, int dy, int status,
int time) {
return super.navigationMovement(dx, dy, status, time);
}
protected void sublayout(int maxWidth, int maxHeight) {
layoutChild(listItems, maxWidth, maxHeight);
setPositionChild(listItems, 5, 0);
setExtent(maxWidth, 255);
}
};
_listVfm.add(listItems);
add(_listVfm);
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
listItems.invalidate();
}
}, 500, true);
}
public void drawListRow(ListField listField, Graphics graphics, int index,
int y, int width) {
TableRowManager rowManager = (TableRowManager) rows.elementAt(index);
rowManager.drawRow(graphics, 0, y, width, listItems.getRowHeight());
}
class TableRowManager extends Manager {
public TableRowManager() {
super(0);
}
public void drawRow(Graphics g, int x, int y, int width, int height) {
layout(width, 250);
setPosition(x, y);
g.pushRegion(getExtent());
subpaint(g);
g.setColor(0x00CACACA);
g.popContext();
}
protected void sublayout(int width, int height) {
int preferredWidth = getPreferredWidth();
Field field = getField(0);
layoutChild(field, preferredWidth, height);
setPositionChild(field, 0, 0);
setExtent(width, height);
}
public int getPreferredWidth() {
return listItems.getWidth();
}
public int getPreferredHeight() {
return listItems.getRowHeight();
}
}
public Object get(ListField listField, int index) {
return null;
}
public int getPreferredWidth(ListField listField) {
return 0;
}
public int indexOfList(ListField listField, String prefix, int start) {
return 0;
}
}
The above code is the part of the code that I am using.How can I implement to view the transparent background.Can anybody please help me.Thanks.
MainScreen includes its own non-transparent background. You'll have to extend Screen if you want to have a transparent/translucent background.
Another option, which I've used in my apps, is using FullScreen instead of MainScreen. FullScreen allows transparent backgrounds. If you're using setStatus or setTitle you'll have to find another method of displaying that data, but otherwise it's very similar.
From your code, though, extending Screen instead of MainScreen would likely by more appropriate.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Image Button in BlackBerry
Is there a way to have a picture be a button in blackberry? Trying to write a matching game.
Ted
below code may help you:
public class ImageButtonFieldTest extends Field {
private Bitmap image;
private Bitmap selectedImage;
private int height;
private int width;
public ImageButtonField(Bitmap image, Bitmap selectedImage) {
this.image = image;
this.selectedImage = selectedImage;
this.height = image.getHeight();
this.width = image.getWidth();
}
protected void layout(int maxWidth, int maxHeight) {
setExtent(image.getWidth(), image.getHeight());
}
protected void paint(Graphics graphics) {
// Draw img
if (isFocus()) {
graphics.drawBitmap(0, 0, width, height, selectedImage, 0, 0);
} else {
graphics.drawBitmap(0, 0, width, height, image, 0, 0);
}
}
public boolean isFocusable() {
return true;
}
protected void drawFocus(Graphics graphics, boolean on) { // Don't draw the default focus
}
protected void onFocus(int direction) {
super.onFocus(direction);
invalidate();
}
protected void onUnfocus() {
super.onUnfocus();
invalidate();
}
}
hi all The below is my code .i try to remove black border color from popup window .i tried this but still i get small black border .
public class S2SPopup extends PopupScreen
{
public S2SPopup()
{
super(new VerticalFieldManager()
{
public void paint(Graphics g)
{
int a = g.getGlobalAlpha();
int c = g.getColor();
g.setColor(c);
g.drawBitmap(0, 0, HomeScreen.popupimg.getWidth(),HomeScreen.popupimg.getHeight(),HomeScreen.popupimg, 0, 0);
super.paint(g);
}
protected void sublayout(int maxWidth, int maxHeight)
{
super.sublayout( HomeScreen.popupimg.getWidth(),HomeScreen.popupimg.getHeight());
setExtent( HomeScreen.popupimg.getWidth(),HomeScreen.popupimg.getHeight());
}
});
setBackground(BackgroundFactory.createSolidTransparentBackground(Color.WHITE, 0));
VerticalFieldManager vfm_Label = new VerticalFieldManager(VerticalFieldManager.VERTICAL_SCROLL)
{
protected void sublayout(int maxWidth, int maxHeight)
{
super.sublayout(maxWidth,150);
setExtent(maxWidth, 150);
}
};
vfm_Label.setMargin(80, 0, 0, 0);
ButtonField btnclose = new ButtonField("",ButtonField.RIGHT)
{
public void paint(Graphics g)
{
//setBackground(BackgroundFactory.createSolidTransparentBackground(Color.WHITE, 0));
int c = g.getGlobalAlpha();
g.setBackgroundColor(c);
super.paint(g);
}
};
btnclose.setMargin(0, 0, 0, 250);
btnclose.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context)
{
close();
}
});
LabelField s2sLabelField = new LabelField()
{
public void paint(Graphics g)
{
g.setColor(Color.BLUE);
super.paint(g);
}
protected void layout(int width, int height)
{
super.layout(width, 150);
setExtent(width, 150);
}
};
s2sLabelField.setPadding(0, 50, 0, 30);
s2sLabelField.setText("lasjdfljlsjlfj ljsfdl jsflljfiowurnowncnvouern.zvovn ljlsfdjj jlj" +
"jsljfdlj ljsfl sjfl jfjsljdfljslfu jsjf;ujerpljsfdjpn sdflsajf ss23s mail jsldfjlfdju nsfjljljlfjmnn,nsf,n,nlojljlsndf,n,ljnsjfdljjufsn jj" +
"sjfd;jjljlsduflja;sfj ljsldfujrqnfqperiujf.zvnpqrue 33333333333333333333333333333333333333 ");
add(btnclose);
vfm_Label.add(s2sLabelField);
add(vfm_Label);
} //end of constructor
} // end of main screen
Override applyTheme with an empty implementation, and the black border goes away. You can't fix this from the constructor alone:
protected void applyTheme(){}
I doubt that it will correct this, but you may try giving your delegate manager a margin of 0 just to be certain that there isn't one on it and background color is creeping in from the theme. A solution that I have implemented in the past is to create your own custom Screen
public class CustomPopup extends Screen {
public CustomPopup() {
super(new VerticalFieldManager() {
//your custom code or a custom manager class (which is what I did)
);
setBackground(BackgroundFactory.createSolidTransparentBackground(0x000000, 0));
}
protected void sublayout(int width, int height) {
//make this screen take up the entire display
setPosition(0, 0);
setExtent(Display.getWidth(), Display.getHeight());
//and layout the delegate
setPositionDelegate(some_x, some_y);
layoutDelegate(some_width, some_height);
}
}
You'll have to add your own buttons and other graphics to it, but This should at least help point you in the right direction.
I have created a custom button and i am placing the bunch of Custombuttons in a verticalfieldManager , I have aligned the verticalField Manager in the center. when i am creating a default buttonField then verticalfield Manager is able to align the buttonfield in the center. but when i am assigning custombuttonfield in the verticalField Manager it's not aligning in the center.
here is my custombuttoncode
public CustomButtonField(String label,long style) {
super(style);
this.label = label;
onPicture = Bitmap.getBitmapResource(onPicturePath);
font = getFont();
this.setPadding(5,5, 5, 5);
}
public String getLabel() {
return label;
}
public int getPreferredHeight() {
return onPicture.getHeight();
}
public int getPreferredWidth() {
return onPicture.getWidth();
}
protected void layout(int width , int height) {
setExtent(Math.min(width, Display.getWidth()), Math.min(height,getPreferredHeight()));
}
protected void paint(Graphics graphics) {
int texty =(getHeight()-getFont().getHeight())/2;
if (isFocus()) {
graphics.setColor(Color.BLACK);
graphics.drawBitmap(0, 0, getWidth(), getHeight(),onPicture , 0, 0);
graphics.setColor(Color.WHITE);
graphics.setFont(font);
graphics.drawText(label,0,texty,DrawStyle.ELLIPSIS,getWidth());
} else {
graphics.drawBitmap(0, 0, getWidth(), getHeight(),onPicture , 0, 0);
graphics.setColor(Color.WHITE);
graphics.setFont(font);
graphics.drawText(label,0,texty,DrawStyle.ELLIPSIS,getWidth());
}
}
public boolean isFocusable() {
return true;
}
protected void onFocus(int direction) {
super.onFocus(direction);
invalidate();
}
protected void onUnfocus() {
super.onUnfocus();
invalidate();
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(0);
return true;
}
protected boolean keyChar(char character, int status, int time) {
if (character == Keypad.KEY_ENTER) {
fieldChangeNotify(0);
return true;
}
return super.keyChar(character, status, time);
}
}
When you create the button you need to pass the Field.FIELD_HCENTER flag as one of your style flags.
CustomButtonField button = new CustomButtonField("TestLabel", Field.FIELD_HCENTER);