Blackberry editfield error - blackberry

I had an custom editfield
public class Custom_EditField extends EditField {
int width, row;
Custom_EditField(long style, int width, int row) {
super(style);
this.width = width;
this.row = row;
}
protected void layout(int width, int height) {
width = this.width;
height = this.row;
super.layout(width, Font.getDefault().getHeight() * row);
super.setExtent(width, Font.getDefault().getHeight() * row);
}
public int getPreferredHeight() {
return Font.getDefault().getHeight() * row;
}
public int getPreferredWidth() {
return width;
}
public void paint(Graphics graphics) {
super.paint(graphics);
graphics.setBackgroundColor(Color.GRAY);
graphics.clear();
graphics.setColor(Color.BLACK);
int labelWidth = getFont().getAdvance(getLabel());
graphics.drawRect(labelWidth, 0, getWidth() - labelWidth, getHeight());
graphics.drawText(this.getText(), 0, 0);
}
}
When I type a full line of word in the editfield, it will cause and error. It seem like cannot auto go to next line.

The arguments to the layout method in BlackBerry UI are maximums, and your custom code makes no attempt to honor those maximums when setting the field extent. This will cause problems with your layout. Also, the paint() method is not the best place to alter drawing for text fields, because it doesn't understand text wrapping. If you want to alter how the text is drawn, but after the wrapping has been performed, you want to override drawText instead.
This is approximately what you want, but you will need to do some more tweaking to make it work the way you expect:
protected void layout(int maxWidth, int maxHeight) {
super.layout(maxWidth, Math.min(maxHeight, Font.getDefault().getHeight() * row));
super.setExtent(maxWidth, Math.min(maxHeight, Font.getDefault().getHeight() * row));
}
public int drawText(Graphics graphics,
int offset,
int length,
int x,
int y,
DrawTextParam drawTextParam) {
graphics.setBackgroundColor(Color.GRAY);
graphics.clear();
graphics.setColor(Color.BLACK);
int labelWidth = getFont().getAdvance(getLabel());
graphics.drawRect(labelWidth, 0, getWidth() - labelWidth, getHeight());
graphics.drawText(this.getText().substring(offset, offset + length), x, y);
}

Related

How to set background image fitable in blackberry application

I have written the following code here the background image is displaying but the image did not cover the full background
private Bitmap background;
int mWidth = Display.getWidth();
int mHeight = Display.getHeight();
public MyScreen()
{
// Set the displayed title of the screen
//backgroundBitmap = Bitmap.getBitmapResource("slidimage.png");
final Bitmap background = Bitmap.getBitmapResource("slidimage.png");
HorizontalFieldManager vfm = new HorizontalFieldManager(USE_ALL_HEIGHT | USE_ALL_WIDTH) {
public void paint(Graphics g) {
g.drawBitmap(0, 0,mWidth, mHeight, background, 0, 0);
super.paint(g);
}
};
add(vfm);
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;
}
You can use the above method to resize the image
just pass the image to be resized and its width and height .
and the function will return the resized image .
where rescale Array is the below method
private static int[] rescaleArray(int[] ini, int x, int y, int x2, int y2)
{
int out[] = new int[x2*y2];
for (int yy = 0; yy < y2; yy++)
{
int dy = yy * y / y2;
for (int xx = 0; xx < x2; xx++)
{
int dx = xx * x / x2;
out[(x2 * yy) + xx] = ini[(x * dy) + dx];
}
}
return out;
}

custom editfield error when next line

I am trying to type in characters to fill an editfield, if the text is still on the first line I have got no problem but when the first line is full then it goes to the next line and I get the following error:
0:01:56.609: Uncaught: StackOverflowError
Here is my custom_editfield:
public class Custom_EditField extends EditField {
int width, row;
Custom_EditField(long style, int width, int row) {
super(style);
this.width = width;
this.row = row;
}
public int getPreferredHeight() {
return Font.getDefault().getHeight() * row;
}
public int getPreferredWidth() {
return width;
}
protected void layout(int maxWidth, int maxHeight) {
super.layout(maxWidth,
Math.min(maxHeight, Font.getDefault().getHeight() * row));
super.setExtent(maxWidth,
Math.min(maxHeight, Font.getDefault().getHeight() * row));
}
/*public int drawText(Graphics graphics, int offset, int length, int x,
int y, DrawTextParam drawTextParam) {
graphics.setBackgroundColor(Color.GRAY);
graphics.clear();
graphics.setColor(Color.BLACK);
int labelWidth = getFont().getAdvance(getLabel());
graphics.drawRect(labelWidth, 0, getWidth() - labelWidth, getHeight());
return graphics.drawText(
this.getText().substring(offset, offset + length), x, y);
}*/
protected void paint(Graphics graphics) {
int rectHeight = getPreferredHeight();
int rectWidth = getPreferredWidth();
graphics.setBackgroundColor(Color.GRAY);
graphics.clear();
graphics.setColor(Color.BLACK);
graphics.drawRect(0, 0, rectWidth, rectHeight);
super.paint(graphics);
}
}
I also noticed that the cursor is transparent. Do you think that the cursor could cause this problem?
Here is I call the editfield
extends VerticalFIeldManager
protected void sublayout(int width, int height) {
comments = new Custom_EditField(Field.FIELD_HCENTER
| Field.FIELD_VCENTER | Field.FOCUSABLE,
getPreferredWidth() - 10, 3);
add(comments);
namelabel = new Custom_LabelField("姓名:", DrawStyle.ELLIPSIS
| LabelField.USE_ALL_WIDTH | DrawStyle.LEFT | Field.FIELD_LEFT);
namelabel.setFont(Font.getDefault().derive(Font.BOLD, 20));
namelabel.setFontColor(Color.BLACK);
add(namelabel);
postbtn = new ButtonField("留言", DrawStyle.HCENTER | Field.FIELD_RIGHT);
postbtn.setPadding(0, 20, 0, 20);
postbtn.setChangeListener(this);
add(postbtn);
name = new Custom_EditField(Field.FIELD_HCENTER | Field.FIELD_VCENTER
| Field.FOCUSABLE, getPreferredWidth()
- namelabel.getPreferredWidth() - postbtn.getContentWidth() - 5
* 4, 1);
add(name);
Field field = getField(0);
layoutChild(field, getPreferredWidth() - 10,
comments.getPreferredHeight());
setPositionChild(field, 5, 5);
field = getField(1);
layoutChild(field, Font.getDefault().getAdvance(namelabel.getText()),
namelabel.getContentHeight());
setPositionChild(field, 5, comments.getPreferredHeight() + 5 * 2);
field = getField(2);
layoutChild(field, postbtn.getPreferredWidth() + postbtn.getWidth(),
name.getPreferredHeight());
setPositionChild(field, getPreferredWidth() - (postbtn.getWidth() + 5),
comments.getPreferredHeight() + 5 * 2);
field = getField(3);
layoutChild(field, getPreferredWidth() * 2 / 3,
name.getPreferredHeight());
setPositionChild(field, namelabel.getWidth(),
comments.getPreferredHeight() + 5 * 2);
width = Math.min(width, getPreferredWidth());
height = Math.min(height, getPreferredHeight());
setExtent(width, height);
}
The Solution
I still can't build your code, because the Manager code posted uses the class Custom_LabelField, which you haven't shown. However, I would assume that Custom_LabelField is somewhat like a LabelField. If I assign name to be a LabelField, then I see your StackOverflowError.
Just as #EugenMartynov said, you are setting the text of a label field inside your implementation of sublayout(). This actually causes sublayout() to be called again, from within itself. This causes namelabel to be created again, and the process repeats infinitely until the stack is exhausted.
Really, the sublayout() method should only be used for layout operations: positioning and sizing. You should normally create your Field objects before that. Normally, that happens in the constructor. If you move the first half of your sublayout method to the constructor, you'll fix this problem:
public class MyManager extends VerticalFieldManager {
public MyManager() {
super(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);
comments = new Custom_EditField(Field.FIELD_HCENTER
| Field.FIELD_VCENTER | Field.FOCUSABLE,
getPreferredWidth() - 10, 3);
add(comments);
namelabel = new Custom_LabelField("姓名:", DrawStyle.ELLIPSIS
| LabelField.USE_ALL_WIDTH | DrawStyle.LEFT | Field.FIELD_LEFT);
namelabel.setFont(Font.getDefault().derive(Font.BOLD, 20));
namelabel.setFontColor(Color.BLACK);
add(namelabel);
postbtn = new ButtonField("留言", DrawStyle.HCENTER | Field.FIELD_RIGHT);
postbtn.setPadding(0, 20, 0, 20);
postbtn.setChangeListener(this);
add(postbtn);
name = new Custom_EditField(Field.FIELD_HCENTER | Field.FIELD_VCENTER
| Field.FOCUSABLE, getPreferredWidth()
- namelabel.getPreferredWidth() - postbtn.getContentWidth() - 5
* 4, 1);
add(name);
}
}
Then sublayout() becomes simpler:
protected void sublayout(int height, int width) {
Field field = getField(0);
layoutChild(field, getPreferredWidth() - 10,
comments.getPreferredHeight());
setPositionChild(field, 5, 5);
field = getField(1);
layoutChild(field, Font.getDefault().getAdvance(namelabel.getText()),
namelabel.getContentHeight());
setPositionChild(field, 5, comments.getPreferredHeight() + 5 * 2);
field = getField(2);
layoutChild(field, postbtn.getPreferredWidth() + postbtn.getWidth(),
name.getPreferredHeight());
setPositionChild(field, getPreferredWidth() - (postbtn.getWidth() + 5),
comments.getPreferredHeight() + 5 * 2);
field = getField(3);
layoutChild(field, getPreferredWidth() * 2 / 3,
name.getPreferredHeight());
setPositionChild(field, namelabel.getWidth(),
comments.getPreferredHeight() + 5 * 2);
width = Math.min(width, getPreferredWidth());
height = Math.min(height, getPreferredHeight());
setExtent(width, height);
}
General Information
If you want to know how to catch a StackOverflowError, put this code in your top level UiApplication subclass (just for debugging ... remove it before releasing your app):
try {
MyApp theApp = new MyApp();
theApp.enterEventDispatcher();
} catch (Throwable e) {
e.printStackTrace();
}
After it hits the line e.printStackTrace(), your Eclipse Console window will show something like this:
[375.664] 0x16
[375.664] HelloBlackBerry(4FF4123E)
[375.664] MyManager
[375.664] sublayout
[375.664] 0x16
[375.664] HelloBlackBerry(4FF4123E)
[375.664] MyManager
[375.664] sublayout
[375.664] 0x16
[375.664] HelloBlackBerry(4FF4123E)
[375.664] MyManager
[375.664] sublayout
[375.664] 0x16
[375.664] HelloBlackBerry(4FF4123E)
[375.664] MyManager
[375.664] sublayout
[375.664] 0x16
[375.664] HelloBlackBerry(4FF4123E)
You can see, over and over, with almost the exact same timestamp (375.664), the sublayout method in the MyManager class is being called. When you see that, you know you need to look at that method, because it's calling itself.

how to create widget in blackberry?

This is my custom layout which was same as android linear layout
public class Custom_TopField extends VerticalFieldManager {
private static final int FIELD_HEIGHT = 70;
private String _text;
Custom_TopField(int color, String text) {
super(Manager.NO_VERTICAL_SCROLL);
_text = text;
Background background = BackgroundFactory.createSolidBackground(color);
setBackground(background);
}
protected void sublayout(int width, int height) {
width = Math.min(width, getPreferredWidth());
height = Math.min(height, getPreferredHeight());
setExtent(width, height);
}
public int getPreferredHeight() {
return FIELD_HEIGHT;
}
public int getPreferredWidth() {
return Display.getWidth();
}
public void paint(Graphics graphics) {
int rectHeight = getPreferredHeight();
int rectWidth = getPreferredWidth();
Font font = Font.getDefault().derive(Font.BOLD, 65);
graphics.drawRect(0, 0, rectWidth, rectHeight);
graphics.drawText(_text, rectWidth / 2, 10);
graphics.setFont(font);
graphics.setColor(Color.WHITE);
super.paint(graphics);
}
}
Output = background red and font = black
What I want is background red, font white, font size 40.
I also want to know how to create widget programmatically?
To set the font to white and the size to 40 change the paint as follows:
public void paint(Graphics graphics) {
int rectHeight = getPreferredHeight();
int rectWidth = getPreferredWidth();
Font font = Font.getDefault().derive(Font.BOLD, 40);
graphics.setColor(Color.WHITE);
graphics.setFont(font);
graphics.drawRect(0, 0, rectWidth, rectHeight);
graphics.drawText(_text, rectWidth / 2, 10);
super.paint(graphics);
}

How will i make this type of list in blackberry?

I want to make this type of customized list .
I have that red color image & i have to fit coming next 5 date n current month on that red image & near to that i want to add four text. I have that white background image of that list with me .
how to do it in blackberry.Please help me ...
You can use "Create a Custom Listfield - Change Highlight Color when Scrolling" from the berrytutorials blog to learn how to create a listField . In the drawListRow method you can get the graphics object and draw the list row as you want.
Use graphics.drawText() to draw text , graphics.drawBitmap() to draw images etc.
This was my requirement Hence I did not go for the listField option...
Try it may be helpful..
listVFM = new VerticalFieldManager();
rowHFM = new HorizontalFieldManager[10];
imageBitmapField = new BitmapField[10];
img_bitmap = Bitmap.getBitmapResource("image.png");
descriptionLabel = new LabelField[10];
discountLabel = new LabelField[10];
goButton = new RoundedCustomButtonField[10];
goSelectBitmap = Bitmap.getBitmapResource("btnSelectGo.png");
goUnselectBitmap = Bitmap.getBitmapResource("btnUnselectGo.png");
row_height = 90;
int j=0;
int row_count = 0;
for(int i=0; i<10; i++) {
rowHFM[row_count] = new HorizontalFieldManager(HorizontalFieldManager.USE_ALL_HEIGHT) {
protected void sublayout(int maxWidth, int maxHeight) {
int displayWidth = Display.getWidth();
int displayHeight = 80;
super.sublayout( displayWidth, displayHeight);
setExtent( displayWidth, displayHeight);
}
};
rowHFM[row_count].setPadding(2, 2, 2, 2);
imageBitmapField[row_count] = new BitmapField(img_bitmap, BitmapField.FIELD_VCENTER | BitmapField.VCENTER | BitmapField.USE_ALL_HEIGHT) {
protected void layout(int maxWidth, int maxHeight)
{
int displayWidth = 85;
int displayHeight = 70;
super.layout( displayWidth, displayHeight);
setExtent( displayWidth, displayHeight);
}
};
imageBitmapField[row_count].setPadding(0,0,0,4);
descriptionLabel[row_count] = new LabelField("Description.....") {
protected void layout(int maxWidth, int maxHeight) {
int displayWidth = (int)(Display.getWidth()/2.6);
int displayHeight = maxHeight;
super.layout( displayWidth, displayHeight);
setExtent( displayWidth, displayHeight);
}
};
descriptionLabel[row_count].setPadding(5,0,0,2);
discountLabel[row_count] = new LabelField(discountRate + "%") {
protected void layout(int maxWidth, int maxHeight) {
int displayWidth = (int)(Display.getWidth()/4.8);
int displayHeight = maxHeight;
super.layout( displayWidth, displayHeight);
setExtent( displayWidth, displayHeight);
}
};
discountLabel[row_count].setPadding(5,0,0,2);
goButton[row_count] = new CustomButtonField("go",goSelectBitmap ,goUnselectBitmap, Field.FIELD_VCENTER |Field.USE_ALL_HEIGHT);
goButton[row_count].setPadding(0,0,0,2);
goButton[row_count].setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
//code....
}
});
rowHFM[row_count].add(imageBitmapField[row_count]);
rowHFM[row_count].add(descriptionLabel[row_count]);
rowHFM[row_count].add(discountLabel[row_count]);
rowHFM[row_count].add(goButton[row_count]);
listVFM.add(rowHFM[row_count]);
row_count++;
}

setExtent for nested HorizontalFieldManagers

I am developing an application where I should use nested horizontalmanagers. I am taking inner and outer HFMs. The fields of innerHFM overlap on the outerHFM when I scroll the fields. How can I use setExtent method for innerHFM. My innerHFM contains fields like 1 2 3 4 5 and my outerHFM contains next and previous buttons. Here is the code I implemented
outerHFM = new HorizontalFieldManager() {
protected void sublayout(int maxWidth, int maxHeight) {
layoutChild(next, maxWidth, maxHeight);
setPositionChild(next, 300, 5);
layoutChild(innerHfm, 200, maxHeight);
setPositionChild(innerHfm, 10, 5);
layoutChild(previous, maxWidth, maxHeight);
setPositionChild(previous, 44, 5);
setExtent(maxWidth, 40);
}
};
innerHfm = new HorizontalFieldManager(Manager.HORIZONTAL_SCROLL|Manager.USE_ALL_WIDTH) {
protected void sublayout(int maxWidth, int maxHeight) {
int space = 0;
int x = 90;
for (int i = 0; i < cardsSize; i++) {
layoutChild(numbtn[i], 210, maxHeight);
setPositionChild(numbtn[i], x + space+offset, 0);
space = space + 50;
}
setExtent(240, 40);
}
};
Hi this sizing works for all my field managers.
int managerWidth;
int managerHeight;
public int getPreferredWidth() {
return managerWidth;
}
public int getPreferredHeight() {
return managerHeight;
}
public void sublayout(int w, int h) {
super.sublayout(managerWidth, managerHeight);
setExtent(managerWidth, managerHeight);
}
maybe that manualy positionig might be problem, you can use AbsoluteFieldManager instead...

Resources