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.
Related
I need to show some links in my application's views. But I can't find anything about it. is it possible??
I want to place browsercontent(field) where gray area for os <5.00 ?
If you want to show a field which is a hyperlink use the following code.
package com.myApp.controls;
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 HrefField extends Field {
private String content;
private Font fieldFont;
private int fieldWidth;
private int fieldHeight;
private boolean active = false;
private int backgroundColour = Color.WHITE;
private int textColour = Color.BLACK;
private int[] drawFocusColors;
public HrefField(String content) {
super(Field.FOCUSABLE);
this.content = content;
fieldFont = Font.getDefaultFont();
fieldWidth = fieldFont.getAdvance(content) + 2;
fieldHeight = fieldFont.getHeight() + 3;
drawFocusColors = new int[] { Color.ORANGE,
Color.ORANGE,Color.RED,
Color.RED};
}
public void setColours(int backgroundColour, int textColour) {
this.backgroundColour = backgroundColour;
this.textColour = textColour;
invalidate();
}
public void setBackgroundColour(int backgroundColour) {
this.backgroundColour = backgroundColour;
invalidate();
}
public void setTextColour(int textColour) {
this.textColour = textColour;
invalidate();
}
public void setMaskColour() {
invalidate();
}
public void setFont(Font fieldFont) {
this.fieldFont = fieldFont;
}
public int getPreferredWidth() {
return fieldWidth;
}
public int getPreferredHeight() {
return fieldHeight;
}
protected void layout(int arg0, int arg1) {
setExtent(getPreferredWidth(), getPreferredHeight());
}
protected void paint(Graphics graphics) {
int[] X_PTS = new int[] { 0, fieldWidth, fieldWidth, 0 };
int[] Y_PTS = { 0, 0, fieldHeight, fieldHeight };
if (active) {
graphics.drawShadedFilledPath(X_PTS, Y_PTS, null, drawFocusColors,
null);
} else {
graphics.setColor(backgroundColour);
graphics.fillRect(0, 0, fieldWidth, fieldHeight);
}
graphics.setColor(textColour);
graphics.setFont(fieldFont);
graphics.drawText(content, 1, 1);
graphics.drawLine(1, fieldHeight - 2, fieldWidth - 2, fieldHeight - 2);
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(1);
return true;
}
protected void onFocus(int direction) {
active = true;
invalidate();
}
protected void onUnfocus() {
active = false;
invalidate();
}
}
How would I go about creating a custom ButtonField that includes an icon? I have found several different sources for a ButtonField with a custom background Bitmap, but I want to have a button with an Icon and text under it. I can not find anyt informaiton about this, maybe someone here could help me out?
Cheers
Try this
package com.MYAPP.controls;
import com.MYAPP.bll.Log;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Characters;
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 ButtonControl extends Field {
private Bitmap selectedBitmap;
private Bitmap unSelectedBitmap;
private String _label;
protected boolean focus = false;
protected int bWidth = 0;
protected int bHeight = 0;
int padding = 0;
Font font=Font.getDefault();
public ButtonControl(String icon, String label) {
super(Field.FOCUSABLE);
_label = label;
try {
selectedBitmap = Bitmap.getBitmapResource(icon + "_focus.png");
unSelectedBitmap =Bitmap.getBitmapResource(icon + ".png");
padding = 0;
} catch (Exception ex) {
Log.Error(ex, "Cannot load icon {" + icon + "}");
}
bWidth = selectedBitmap.getWidth();
bHeight = selectedBitmap.getHeight();
}
protected void onFocus(int direction) {
focus = true;
invalidate();
}
protected void onUnfocus() {
focus = false;
invalidate();
}
public void drawFocus(Graphics g, boolean on) {
// do nothing... this is handled in paint...
}
protected int moveFocus(int amount, int status, int time) {
// This ensures background is redrawn properly if this control is
// the first or last in a series (eliminate white background issue)
invalidate();
return super.moveFocus(amount, status, time);
}
protected void moveFocus(int x, int y, int status, int time) {
// This ensures background is redrawn properly if this control is
// the first or last in a series (eliminate white background issue)
invalidate();
super.moveFocus(x, y, status, time);
}
int _labelWidth;
int posbitmapX=0;
int x=0;
int y = 0;
protected void paint(Graphics g) {
int oldColor = g.getColor();
Font oldFont = g.getFont();
g.setFont(getTextFont());
x = (getWidth() - bWidth) / 2;
if (focus) {
g.setColor(Color.WHITE);
g.drawBitmap(x, y, bWidth, bHeight, selectedBitmap, 0, 0);
} else {
g.setColor(Color.BLACK);
g.drawBitmap(x, y, bWidth, bHeight, unSelectedBitmap, 0, 0);
}
g.setFont(getTextFont());
_labelWidth = getTextFont().getAdvance(_label);
g.drawText(_label, 0, bHeight + 2, Graphics.HCENTER, getWidth());
g.setColor(oldColor);
g.setFont(oldFont);
}
protected void layout(int width, int height) {
setExtent(getPreferredWidth(), getPreferredHeight());
}
private Font getTextFont() {
return font;
}
public int getPreferredWidth() {
return selectedBitmap.getWidth();
}
public int getPreferredHeight() {
return (bHeight + 2 + font.getHeight() + 2);
}
protected boolean keyChar(char key, int status, int time) {
if (key == Characters.ENTER) {
return this.navigationClick(status, time);
}
return super.keyChar(key, status, time);
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(1);
return true;
}
protected void fieldChangeNotify(int context) {
try {
this.getChangeListener().fieldChanged(this, context);
} catch (Exception e) {
Log.Debug("Error responding to field change: " + e);
}
} }
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.
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);
}
}
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);