GridFieldManager Blackberry align fields - blackberry

I have a GridFieldManager whith 3 columns and I want to align their content like this:
|Title left | Title Center | Title Right|
The problem is that I'm using a RichTextField instead of a LabelField because I want the text of each title to grap like this:
|Title left | Title Center | Title Right |
|is wrapped | is wrapped too | also wrapped |
If I use RichTextField instead of LabelField, then, the the alignment is ignored. This is my code:
public class CustomGridFieldextends GridFieldManager {
private int numColumns = 3;
private int margin = 5;
public CustomGridField(String leftText, String centerText, String rightText) {
super(1, 3, GridFieldManager.USE_ALL_WIDTH);
setPadding(0, margin, 0, margin);
int columnWidth = (Display.getWidth() / numColumns);
for (int i = 0; i < numColumns; i++) {
setColumnProperty(i, GridFieldManager.FIXED_SIZE, columnWidth);
}
// leftmost text
RichTextField leftLabel = new RichTextField(leftText){
protected void paint(Graphics g) {
g.setColor(Color.WHITE);
g.setFont(getFont().derive(Font.BOLD));
super.paint(g);
}
};
leftLabel.setFont(getFont().derive(Font.BOLD));
add(leftLabel, Field.FIELD_LEFT);
// center text
RichTextField centerLabel = new RichTextField(centerText){
protected void paint(Graphics g) {
g.setFont(getFont().derive(Font.BOLD));
g.setColor(Color.WHITE);
super.paint(g);
}
};
centerLabel.setFont(getFont().derive(Font.BOLD));
add(centerLabel, Field.FIELD_HCENTER);
// rightmost text
RichTextField rightLabel = new RichTextField(rightText) {
protected void paint(Graphics g) {
g.setFont(getFont().derive(Font.BOLD));
g.setColor(Color.WHITE);
super.paint(g);
}
};
rightLabel.setFont(getFont().derive(Font.BOLD));
add(rightLabel, Field.FIELD_RIGHT);
}
protected void paintBackground(Graphics g) {
// draw a nice background...
}
}

Found the answer, turns out that I had to use this styles when creating the RichTextFields:
new RichTextField("text on left",RichTextField.TEXT_ALIGN_LEFT);
new RichTextField("text on center",RichTextField.TEXT_ALIGN_HCENTER);
new RichTextField("text on right",RichTextField.TEXT_ALIGN_RIGHT);
Now I'm working on the grapping...
PD: found it here: http://v4ks1n.wordpress.com/2009/04/16/richtextfield-alignment/

Related

Scroll only single listfield in multiple listfields blackberry

I'm new to blackberry and I've a question, I've 3 listfields in a row like
[--------One--------][--Two--][--Three--]
but when I scroll single one, every one scrolls!, how do I restrict scroll of others when focused one is scrolling?
EDIT
// ListFields
HorizontalFieldManager hfmMain = new HorizontalFieldManager();
HorizontalFieldManager hfmFist = new HorizontalFieldManager(FIELD_LEFT);
hfmFist.add(myListView);
HorizontalFieldManager hfmSecond = new HorizontalFieldManager();
hfmSecond.add(hizabListView);
HorizontalFieldManager hfmThird = new HorizontalFieldManager();
hfmThird.add(paraListView);
hfmMain.add(hfmFist);
hfmMain.add(hfmSecond);
hfmMain.add(hfmThird);
add(hfmMain);
The key is that you need to disable vertical scrolling for the Screen that contains all these managers and fields.
Then, you can create one horizontal field manager. And then, three vertical field managers. Put each list in its own vertical field manager, and then all three vertical field managers go into the horizontal field manager.
Here's a simple prototype that I tested:
public class ListFocusScreen extends MainScreen implements ListFieldCallback {
private ObjectListField list1;
private ListField list2;
private ListField list3;
private Bitmap icon2; // for list 2 cell background
private Bitmap icon3; // for list 3 cell background
public ListFocusScreen() {
// Do NOT allow vertical scrolling at the Screen level!!
super(MainScreen.NO_VERTICAL_SCROLL | MainScreen.NO_VERTICAL_SCROLLBAR);
// A container for the "row" of three side-by-side lists
HorizontalFieldManager hfm = new HorizontalFieldManager(Field.USE_ALL_WIDTH);
// Do create a vertical field manager for each list, that scrolls
VerticalFieldManager vfm1 = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR) {
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(2 * Display.getWidth() / 3, maxHeight); // 2/3 width
}
};
VerticalFieldManager vfm2 = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR) {
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth() / 6, maxHeight); // 1/6 width
}
};
VerticalFieldManager vfm3 = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR) {
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth() / 6, maxHeight); // 1/6 width
}
};
Object[] listData1 = new Object[24];
for (int i = 0; i < listData1.length; i++) {
// generate fake data for list1
listData1[i] = String.valueOf(i) + ". Click to Download";
}
list1 = new ObjectListField();
list1.set(listData1);
list2 = new ListField();
list2.setCallback(this);
icon2 = Bitmap.getBitmapResource("octagon.png");
list2.setSize(15);
list3 = new ListField();
list3.setCallback(this);
icon3 = Bitmap.getBitmapResource("frame.png");
list3.setSize(15);
vfm1.add(list1);
vfm2.add(list2);
vfm3.add(list3);
hfm.add(vfm1);
hfm.add(vfm2);
hfm.add(vfm3);
add(hfm);
}
public void drawListRow(ListField listField, Graphics graphics, int index,
int y, int width) {
// this same method will be used for custom drawing of both lists 2 and 3
final int PAD = 4;
String text = (String)get(listField, index);
if (listField == list2) {
graphics.drawBitmap(0, y, width, width, icon2, 0, 0);
graphics.drawText(text, PAD, y + PAD);
} else if (listField == list3) {
graphics.drawBitmap(0, y, width, width, icon3, 0, 0);
graphics.drawText(text, PAD, y + PAD);
}
}
public Object get(ListField listField, int index) {
// TODO: normally, get this value from a vector of actual
// data for each list
return String.valueOf(index);
}
public int getPreferredWidth(ListField listField) {
return Display.getWidth() / 6;
}
public int indexOfList(ListField listField, String prefix, int start) {
return -1; // no search support
}
}
Results
As you can see, I was able to get each list scrolling vertically, independently.
You have several list fields into one screen manager and when you scroll down and when this manager is selected, then the scroll event is being sent to all these fields. And all of them are scrolling simultaneously.
I would separate every listfield into its own manager.

Custom layout in blackberry

I need a custom layout as below in BlackBerry.
I did same layout in Android. Now I need same layout in BlackBerry. I am new to BlackBerryapp development. The Fields of BlackBerry like Views in Android seem to be very confusing things to me.
I tried with VerticalFieldManager & HorizontalFieldManager by mixing these with BitmapField & LabelField to produce my layout.
I failed particularly in placing LabelField at bottom of screen. I used USE_ALL_HEIGHT & FIELD_BOTTOM style to put at bottom, but it is showing after scrolling long time.
My requirement is the header and footer should not scroll when my middle list is scrolling.
The easiest way to add header and footer fields that don't scroll with the content in the middle of the screen is to use MainScreen#setBanner() and MainScreen#setStatus().Here's an example:
public class HeaderFooterListScreen extends MainScreen {
private static final int BG_COLOR = Color.BLACK;
private static final int HIGHLIGHT_COLOR = Color.BLUE;
private static final int FONT_COLOR = Color.WHITE;
private static final int ROW_HEIGHT = 60;
private Object[] _rowData;
private Field _header;
private Field _footer;
private Field _spacer;
private int _orientation;
public HeaderFooterListScreen() {
super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);
Background bg = BackgroundFactory.createSolidBackground(BG_COLOR);
setBackground(bg);
getMainManager().setBackground(bg);
// header
Bitmap headerImg = Bitmap.getBitmapResource("header.png");
_header = new BitmapField(headerImg);
setBanner(_header);
// list
_rowData = new Object[] { "row one", "row two", "row three" }; //, "row four", "row five", "row six", "row seven", "row eight", "row nine", "row ten" };
ListField list = new ListField();
int c = Color.RED;
XYEdges edgeColors = new XYEdges(c, c, c, c);
XYEdges edgeThicknesses = new XYEdges(5, 5, 5, 5);
list.setBorder(BorderFactory.createSimpleBorder(edgeThicknesses, edgeColors, Border.STYLE_SOLID));
list.setCallback(new CustomListFieldCallback());
list.setRowHeight(ROW_HEIGHT);
list.setSize(_rowData.length);
add(list);
// footer
_footer = new LabelField("Footer Showing Status As Text", Field.USE_ALL_WIDTH | DrawStyle.HCENTER) {
public void paint(Graphics g) {
// change font color
int oldColor = g.getColor();
g.setColor(FONT_COLOR);
super.paint(g);
g.setColor(oldColor);
}
};
_footer.setFont(_footer.getFont().derive(Font.PLAIN, 24));
setStatus(_footer);
}
private void centerList() {
if (_spacer != null && _spacer.getManager() != null) {
// delete the old spacer field, if there was one
delete(_spacer);
}
int listHeight = _rowData.length * ROW_HEIGHT;
int availableHeight = getHeight() - _footer.getHeight() - _header.getHeight();
if (availableHeight > listHeight) {
boolean firstRun = (_spacer == null);
// add a spacer above the list to force it down enough to be centered
final int SPACE = (availableHeight - listHeight) / 2;
_spacer = new Field() {
protected void layout(int width, int height) {
setExtent(width, SPACE);
}
protected void paint(Graphics graphics) {
}
};
insert(_spacer, 0);
if (firstRun) {
getMainManager().setVerticalScroll(0);
}
}
}
// called when device orientation changes
protected void sublayout(int width, int height) {
super.sublayout(width, height);
if (_orientation != Display.getOrientation()) {
_orientation = Display.getOrientation();
// run with invokeLater() to avoid recursive sublayout() calls
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
// TODO: may have to adjust header, too?
centerList();
}
});
}
}
private class CustomListFieldCallback implements ListFieldCallback {
private final int PAD = 10;
public void drawListRow(ListField listField, Graphics graphics,
int index, int y, int width) {
int oldColor = graphics.getColor();
if (listField.getSelectedIndex() == index) {
graphics.setColor(HIGHLIGHT_COLOR);
} else {
graphics.setColor(BG_COLOR);
}
graphics.fillRect(0, y, width, listField.getRowHeight());
graphics.setColor(FONT_COLOR);
String text = (String)get(listField, index);
graphics.drawText(text, PAD, y + PAD, DrawStyle.LEFT);
graphics.setColor(oldColor);
}
public Object get(ListField listField, int index) {
return _rowData[index];
}
public int getPreferredWidth(ListField listField) {
return Display.getWidth();
}
public int indexOfList(ListField listField, String prefix, int start) {
return -1; // TODO?
}
}
}
You didn't specify how you wanted the list in the middle to work, so I just made some guesses. I also wasn't sure if the red border was something you wanted, or just something you used to describe your layout. Edit your question, or post a new question, if you have more requirements for the list.
Field Concepts
If you're coming from Android, and are unclear about the role of BlackBerry UI classes, like Fields and Managers, here's some resources:
another Stack Overflow answer I posted
BlackBerry Advanced UI Sample Code on Github
BlackBerry Layout Managers Tutorial
Results

Put FieldManager at center of the screen in a BlackBerry app

I know about how to put field on the center of the screen with horizontally and vertically.
However I got success with the field, but I want to set the VerticalFieldManager or HorizontalFieldManage to the center of the screen.
My code is like below, but I am not able to set it at center of the screen.
final Bitmap scale = new Bitmap(Display.getWidth(),Display.getHeight());
_backgroundBitmap.scaleInto(scale, Bitmap.FILTER_LANCZOS);
//==============================
// this manager is used for the static background image
mainManager = new VerticalFieldManager(Manager.USE_ALL_HEIGHT | Manager.USE_ALL_WIDTH | Manager.VERTICAL_SCROLL) {
public void paint(Graphics graphics) {
graphics.clear();
graphics.drawBitmap(0, 0, deviceWidth, deviceHeight,scale, 0, 0);
super.paint(graphics);
}
};
// this manger is used for adding the componentes
subManager = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR) {
/*protected void sublayout(int maxWidth, int maxHeight) {
int displayWidth = deviceWidth;
int displayHeight = deviceHeight;
super.sublayout(displayWidth, displayHeight);
setExtent(displayWidth, displayHeight);
}*/
};
VerticalFieldManager dataManager = new VerticalFieldManager(){};
dataManager.setMargin(20, 20, 20, 20);
//CategoryListLayout
//===============================================================================
//====================================
HorizontalFieldManager categoryLayout = new HorizontalFieldManager(FIELD_VCENTER | USE_ALL_WIDTH | FIELD_HCENTER){
protected void paint(Graphics graphics) {
graphics.setColor(0xFFFFFFFF);
super.paint(graphics);
}
};
LabelField cateName = new LabelField("Category", FIELD_VCENTER){
protected void layout(int width, int height) {
super.layout(width, height);
this.setExtent(150, this.getHeight());
}
};
categoryLayout.setBorder(myBorder);
//choice_country.setMinimalWidth(30);
choice_country.setMargin(10, 10, 10, 10);
categoryLayout.add(cateName);
categoryLayout.add(new BitmapField(Bitmap.getBitmapResource("vertical_line.png"), FIELD_VCENTER));
categoryLayout.add(choice_country);
dataManager.add(categoryLayout);
//===============================================================================
//DistanceListLayout
//===============================================================================
HorizontalFieldManager distanceLayout = new HorizontalFieldManager(FIELD_VCENTER | USE_ALL_WIDTH | FIELD_HCENTER){
protected void paint(Graphics graphics) {
graphics.setColor(0xFFFFFFFF);
super.paint(graphics);
}
};
LabelField distName = new LabelField("Distance", FIELD_VCENTER){
protected void layout(int width, int height) {
super.layout(width, height);
this.setExtent(150, this.getHeight());
}
};
distanceLayout.setBorder(myBorder);
//choice_distance.setMinimalWidth(300);
choice_distance.setMargin(10, 10, 10, 10);
distanceLayout.add(distName);
distanceLayout.add(new BitmapField(Bitmap.getBitmapResource("vertical_line.png"), FIELD_VCENTER));
distanceLayout.add(choice_distance);
dataManager.add(distanceLayout);
//===============================================================================
listNames = new Vector();
listImage = new Vector();
//new GetList().execute(null);
ButtonField b_search = new ButtonField("Search", ButtonField.CONSUME_CLICK | ButtonField.FIELD_HCENTER);
b_search.setMargin(10,10,10,10);
b_search.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
if (choice_country.getSelectedIndex() != 0
|| choice_distance.getSelectedIndex() != 0) {
new SubmitSearch().execute(null);
} else {
Dialog.alert("Select atleast One of Two(Category/Distance).");
}
}
});
dataManager.add(b_search);
removeAllScreen();
subManager.add(dataManager);
mainManager.add(subManager);
add(mainManager);
What's wrong in my code?
Update
Here I am using mainManager to display the Background of the app.
subManager is just for container. datamanager is to include mane HorizontalFieldManager.
Now I want is the datamanager is to be display vertically at center of the screen. It not depend on the HorizontalLayout I am going to add in it.
VerticalManager will ignore any vertical modificators like FIELD_VCENTER.
You have to implement your own Manager which will put submanager to center of the screen. Something like this:
protected void sublayout(int maxWidth, int maxHeight) {
submanager.sublayout(displayWidth, displayHeight);
//after sublayout submanager knows his real dimensions
int submanagerWidth = submanager.getWidth();
int submanagerHeight = submanager.getHeight();
int x = (displayWidth - submanagerWidth) >> 1;
int y = (displayHeight - submanagerHeight) >> 1;
setPositionChild(submanager, x, y);
setExtent(displayWidth, displayHeight);
}
In example I assumed that submanager is only one child. But is there are several it's clear how to modify example.
UPDATE
If there are several children (for example 2):
protected void sublayout(int maxWidth, int maxHeight) {
int height = 0;
for (int i = 0; i < 2; i++) {
submanager[i].sublayout(displayWidth, displayHeight);
height += submanager[i].getHeight();
}
int y = (displayHeight - height) >> 1;
if (y < 0)
y = 0;
for (int i = 0; i < 2; i++) {
int submanagerWidth = submanager[i].getWidth();
int submanagerHeight = submanager[i].getHeight();
int x = (displayWidth - submanagerWidth) >> 1;
setPositionChild(submanager[i], x, y);
y += submanagerHeight;
}
setExtent(displayWidth, max(height, submanagerHeight));
}
Why don't you use something like this?
mainManager = new VerticalFieldManager(Manager.USE_ALL_HEIGHT |
Manager.USE_ALL_WIDTH |
Manager.VERTICAL_SCROLL |
DrawStyle.HCENTER /* or DrawStyle.VCENTER */)

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;
}

accessing Inner class while creating BitmapField & adding it in HorizontalFieldManager

I'm creating a inner class in a method. After that I am accessing some statements like,
public class Test extends MainScreen
{
HorizontalFieldManager hfm;
Bitmap bitmap[] = new Bitmap[100];
BitmapField[] bitmapField = new BitmapField[100];
int countBitmap = 0;
Test()
{
VerticalFieldManager vfm_Main = new VerticalFieldManager();
hfm = new HorizontalFieldManager(HorizontalFieldManager.USE_ALL_WIDTH);
vfm_Main.add(hfm);
add(vfm_Main);
}
void drawBitmap()
{
bitmap[countBitmap] = new Bitmap(100, 100);
bitmapField[countBitmap] = new BitmapField(bitmap[countBitmap]){
public void paint(Graphics g)
{
................
................
g.drawLine(x1,y1,x2,y2);
}
}
synchronized(UiApplication.getEventLock())
{
for(int i = 0 ; i < bitmapField.length; i++)
{
if(bitmapField[i] != null)
{
bitmapField[i].setBitmap(bitmap[i]);
}
}
hfm.add(bitmapField[countBitmap]);
countBitmap++;
But here the problem is after creating the bitmap & before creating the bitmapField, control goes to
synchronized(UiApplication.getEventLock()){hfm.add(bitmapField[countBitmap]); }
So before creating the bitmapField, it adds it in hfm.
So the output is coming like "Everytime a new BitmapField is added in hfm (means at the same position by replacing the previous one)". But I want the BitmapFields come next to each other in hfm.
How to do it?
Any solution why the control goes first to hfm.add() before the new bitmapField() inner class?
first of all, several suggestions about code:
see no reason using synchronized since it's UI thread
don't setBitmap, bitmap is already passed to BitmapField constructor
actually all BitmapFields come next to each other in hfm, to make it clear, I've add number to each one.
if you want some custom constructor or new fields in BitmapField, it's better to create new class as an extension of BitmapField
class TestScr extends MainScreen {
HorizontalFieldManager hfm;
Bitmap bitmap[] = new Bitmap[100];
BitmapField[] bitmapField = new BitmapField[100];
TestScr() {
hfm = new HorizontalFieldManager();
add(hfm);
drawBitmap();
}
void drawBitmap() {
for (int i = 0; i < 5; i++) {
bitmap[i] = new Bitmap(50, 50);
Graphics graphics = new Graphics(bitmap[i]);
graphics.setColor(Color.RED);
String number = Integer.toString(i);
Font font = graphics.getFont().derive(Font.BOLD, 40, Ui.UNITS_px);
graphics.setFont(font);
int textWidth = graphics.getFont().getAdvance(number);
int textHeight = graphics.getFont().getHeight();
int x = (bitmap[i].getWidth() - textWidth) / 2;
int y = (bitmap[i].getHeight() - textHeight) / 2;
graphics.drawText(number, x, y);
bitmapField[i] = new BitmapField(bitmap[i]) {
public void paint(Graphics g) {
super.paint(g);
int width = getWidth() - 1;
int height = getHeight() - 1;
g.setColor(Color.GREEN);
g.drawLine(0, 0, width, 0);
g.drawLine(width, 0, width, height);
g.drawLine(width, height, 0, height);
g.drawLine(0, height, 0, 0);
}
};
hfm.add(bitmapField[i]);
}
}
}

Resources