Reducing Blackberry OS 5.0 DateField Height - blackberry

Trying to reduce the height of a DateField from default 53 to 32, but to no avail. The height stays the same with the result that the text appears cut out towards the bottom of the background which is smaller in height (32).
I tried 2 ways:
DateField dtf = new DateField(label, defaultDateTime, DateField.DATE_TIME | DrawStyle.LEFT | DrawStyle.TOP | Field.FOCUSABLE | Field.READONLY )
{
protected void layout(int width, int height)
{
Bitmap bmp = UIElements.GetBitmap(UIElements.IMG_DROPDOWN_BG, true);
width = bmp.getWidth();
height = bmp.getHeight();
super.setExtent(width, height);
super.layout(width, height);
}
};
2nd method (based on a Stack Overflow post):
public class MyDateManager extends VerticalFieldManager {
protected DateField dateField_ = null;
public MyDateManager(String label, long defaultDateTime) {
super(Manager.FIELD_HCENTER | Manager.FIELD_VCENTER);
dateField_ = new DateField(label, defaultDateTime, DateField.DATE_TIME |
Field.FIELD_HCENTER | DrawStyle.HCENTER | Field.FOCUSABLE | Field.READONLY);
this.add(dateField_);
}
protected void sublayout(int width, int height) {
Bitmap bmp = UIElements.GetBitmap(UIElements.IMG_DROPDOWN_BG, false);
width = bmp.getWidth();
height = bmp.getHeight();
layoutChild(dateField_, width, height);
dateField_.setBackground(BackgroundFactory.createBitmapBackground(bmp, 0, 0, Background.REPEAT_NONE));
int h = dateField_.getHeight();
setExtent(width, height);
}
}
Please suggest.
Thanks

Second method is a horrible approach (messing with VerticalFieldManager's height will get you a lot of problems).
Try the first method again, but this time call super.layout first:
DateField dtf = new DateField(label, defaultDateTime, DateField.DATE_TIME | DrawStyle.LEFT | DrawStyle.TOP | Field.FOCUSABLE | Field.READONLY )
{
protected void layout(int width, int height) {
super.layout(width, height);
Bitmap bmp = UIElements.GetBitmap(UIElements.IMG_DROPDOWN_BG, true);
width = bmp.getWidth();
height = bmp.getHeight();
super.setExtent(width, height);
}
};
Notice that using this approach you might also get glitches, as you are blindly overriding a method without considering the rest of the class. To do this safely you would need to have access to the parent class source, and you don't.
I'd suggest to extend HorizontalFieldManager (override sublayout) to have a fixed height (Never VFM because the scrolling goes in the same direction you are trying to make fixed). Then place inside a regular date field that uses all the available height (pass the flag Field.USE_ALL_HEIGHT in the constructor).
More info:
http://docs.blackberry.com/es-es/developers/deliverables/29251/Determining_the_dimensions_of_a_field_1578864_11.jsp

I suspect this is a battle you are likely to loose.
Personally I would create a DateField look-a-like from a LabelField which will give you the restrictions that you need.
DateField is a specialised Field and in my testing, it will ignore the limitations you put upon it, regardless of whether you try to do this via the containing Manager or directly in the Field's layout method. It seems the actual height it will choose for itself will vary by device.
I suspect on all touchscreen capable devices, it will try to give itself enough height to be touched. In terms of pixels that will depend on the resolution (dpi) of the device, as in fact your image should, because it will look different on a high resolution device, like the 9900 to a low resolution device, like the 9300.
I suspect on non-touchscreen devices, it will probably follow the font size specified.
I tested the following code:
DateField dtf1 = new DateField("test1", System.currentTimeMillis(), DateField.DATE_TIME | DrawStyle.LEFT | DrawStyle.TOP | Field.FOCUSABLE | Field.READONLY ) {
protected void layout(int width, int height) {
super.layout(width, 32);
System.out.println("height1: " + Integer.toString(this.getHeight()));
}
};
DateField dtf2 = new DateField("test2", System.currentTimeMillis(), DateField.DATE_TIME | DrawStyle.LEFT | DrawStyle.TOP | Field.FOCUSABLE ) {
protected void layout(int width, int height) {
super.layout(width, 32);
System.out.println("height2: " + Integer.toString(this.getHeight()));
}
};
DateField dtf3 = new DateField("test3", System.currentTimeMillis(), DateField.DATE_TIME | DrawStyle.LEFT | DrawStyle.TOP | Field.FOCUSABLE ) {
protected void layout(int width, int height) {
super.layout(width, 32);
System.out.println("height3: " + Integer.toString(this.getHeight()));
}
};
...
add(dtf1);
add(dtf2);
Font smallFont = this.getFont().derive(Font.PLAIN, 15);
dtf3.setFont(smallFont);
add(dtf3);
On a 9800, the DateField was always 40 pixels in height. On a 9300 is was 18 for the first 2 and 15 for the third.
So, since you are using this DateField just to display a non updateable value, I recommend instead you look at using something like SimpleDateFormat, to format the date as you want, and display this in a LabelField. You can then manage the height of the Field using the Font you specify.

Related

Blackberry background image?

I have searched but haven't find out any solution, i have but its creating problems. when I insert this it says illegal argument and doesn't start.
Bitmap bitmap = Bitmap.getBitmapResource("Background.png");
this.getMainManager().setBackground(
BackgroundFactory.createBitmapBackground(bitmap)
);
It doesn't work.
Thanks for helping! Its working. Just a typo error of my path
tyy this -
final Bitmap top = Bitmap.getBitmapResource("your background image.png");
final VerticalFieldManager top_ = new VerticalFieldManager(Manager.NO_HORIZONTAL_SCROLL | Manager.NO_HORIZONTAL_SCROLLBAR | Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR | Field.USE_ALL_WIDTH){
public void paint(Graphics graphics) {
graphics.drawBitmap(0, 0, top.getWidth(),
top.getHeight(), top, 0, 0);
super.paint(graphics);
}
};
Now you add all your fields to this top_. then add the top_ to your screen. If there is no fields, it will not display the background image. so Dont forget to add some fields.

Multiple column list field

I am facing issue while displaying multiple columns in a row. I need multiple columns and multiple row list field. Now I am trying to make this using label field i one of my case its working quite good but in another case I am facing an issue please help me out. My code is:
VerticalFieldManager TOrderVFM = new VerticalFieldManager()
for ( int i = 0; i <10; i++)
{
HorizontalFieldManager temphfm1 = new HorizontalFieldManager(){
protected void sublayout(int width, int height)
{
int w = 480;
int h = 400;
super.sublayout(w, h);
super.setExtent(w, h);
}
};
TOrderVFM.add(temphfm1);
temphfm1.add(createDayName1(MTradeOrderSoap.objects[i].getProperty("orderDate").toString()));
temphfm1.add(createDayName1(MTradeOrderSoap.objects[i].getProperty("id").toString()));
temphfm1.add(.createDayName1(MTradeOrderSoap.objects[i].getProperty("label").toString()));
temphfm1.add(createDayName1(MTradeOrderSoap.objects[i].getProperty("quantityPending").toString()));
temphfm1.add(createDayName1(MTradeOrderSoap.objects[i].getProperty("securityName").toString()));
temphfm1.add(createDayName1(MTradeOrderSoap.objects[i].getProperty("priceType").toString()));
temphfm1.add(createDayName1(MTradeOrderSoap.objects[i].getProperty("orderOrigin").toString()));
temphfm1.add(ut.createDayName1(MTradeOrderSoap.objects[i].getProperty("orderStatus").toString()));
}
This loop is inserting values that are coming from the soap response and passing it to the method named createDayName() which is also given below.Now this all works good for my one of the screens but when i try to follow this for my another screen i am facing an error:-WARNING: Cannot layout field, insufficient height or width
I have set the width and height of both the managers but nothing seems to be working .Please provide me a support to do that.
public LabelField createDayName1(final String day)
{
LabelField cell = new LabelField("", Field.NON_FOCUSABLE) {
protected void layout(int width, int height)
{
int w = Display.getWidth()/7;
int h = 40;
super.layout(w, h);
super.setExtent(w, h);
}
protected void paint(Graphics g)
{
g.setColor(0xFF9912);
g.setFont(dayNameFont);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
// g.setColor(0x466385);
g.drawText(day.trim(), getWidth() / 2 - dayNameFont.getAdvance(day) / 3, getHeight() / 3 - dayNameFont.getHeight() / 2);
super.paint(g);
}
};
return cell;
}
In layout() and sublayout() you need to make sure you're comparing the width and height you are passing to setExtent() (and super.layout()/super.sublayout() for that matter) to the arguments getting sent to those methods because they are the maximum available width and height. If you try to tell the Field to be wider or taller (using setExtent()) than what is available, it won't be able to display properly.

Background image behind two fields in custom HorizontalFieldManager

Below code defines a horizontal field manager with two fields. How can I amend the code so that the background is just set on the two fields being added not on the whole manager. Note, im not attempting to add an individual background image to each of the fields, instead a shared background image that spans behind the two fields.
LabelField label = new LabelField("name");
TextField e = new TextField(Field.FOCUSABLE);
final Bitmap b = Constants.SETTINGS;
final Background bg = BackgroundFactory.createBitmapBackground(Constants.SETTINGS);
HorizontalFieldManager manager = new HorizontalFieldManager()
{
public void sublayout (int width, int height)
{
Field field;
int x = 0;
super.sublayout(b.getWidth(), height);
super.setExtent(b.getWidth(), height);
for (int i = 0; i < getFieldCount(); i++)
{
field = getField(i);
layoutChild(field, Display.getWidth()/2, height);
setPositionChild(field, x, 10);
x += Display.getWidth()/2;
}
}
};
manager.add (label);
manager.add (e);
add (manager);
Rather than putting them in a custom Manager, it may be easier to just override the Fields' layout() calls to be
protected void layout(int width, int height) {
super.layout(width, height);
setExtent(Display.getWidth()/2, this.getHeight());
}
and then you can just use a normal HorizontalFieldManager you can set a background on and a padding (hfm.setPadding(10, 10, 10, 10);). Adding a padding will reduce the available width for your Fields, so you should decrease their widths in the layout() calls.
You can offset each of their individual backgrounds with some fancy, expensive Bitmap footwork (math) to appear to "share" one image using setBackGround(), or you can override their draw methods to achieve the same effect with the ability to "move" across the bitmap according to their relative position...
That what you're after? :)
edit:
create a custom field to use your bitmap and feed it whatever content you would like, then override the paint to draw what you like where you like it...
protected void paint(Graphics g){
// conditionals, etc
g.drawBitmap(x, y, width, height, bitmap, left, top);
// color changes, etc
g.drawText(yourText);
// clean up
}

GridFieldManager will not span the entire screen width

Ok, I'm developing for the blackberry Bold 9700 and I'm trying to get a 1X4 grid (1 row, 4 columns) to span the entire width of the blackberry screen, but it keeps coming up short. I mean, the grid is aligned to the left by default, which is fine if I can get the whole grid to span the entire width (it won't matter then). Can some developer tell me what I'm doing wrong? I thought you just add GridFieldManager.USE_ALL_WIDTH in the constructor when declaring a new grid but it still won't work for me.
final class App3_MainScreen extends MainScreen {
private int numColumns, size;
// Constructor
App3_MainScreen() {
// declare a layout manager to take care of all the layout stuff
numColumns = 4;
size = 4;
VerticalFieldManager vfm = new VerticalFieldManager();
vfm.add(new LabelField("using all width & long label...", LabelField.ELLIPSIS | Field.FIELD_HCENTER));
int borderHeight = Display.getHeight()/2;g
int borderWidth = Display.getWidth()/2;
Manager gridFieldManager = new GridFieldManager(1, 4, GridFieldManager.USE_ALL_WIDTH | GridFieldManager.AUTO_SIZE); // 1 row and 4 columns
gridFieldManager.add(new ButtonField(""+borderHeight, Field.FIELD_HCENTER));
gridFieldManager.add(new ButtonField("222", Field.FIELD_HCENTER));
gridFieldManager.add(new ButtonField("333", Field.FIELD_HCENTER));
gridFieldManager.add(new ButtonField(""+borderWidth, Field.FIELD_RIGHT));
// set padding around each buttonField - top=0, right=5, bottom=0, left=5
gridFieldManager.setPadding(0, 5, 0, 5);
int gfmHeight = 48 * (size / numColumns);
gridFieldManager.setBorder(BorderFactory.createSimpleBorder(
new XYEdges(borderHeight/10, 0, borderHeight/10, 0), // top, right, bottom, left
Border.STYLE_DASHED));
add(gridFieldManager);
}}
I've provided an example below that does the trick. It's based on the original code you provided, but is cleaned up and made generic for clarity.
Basically, GridFieldManager doesn't explicitly support USE_ALL_WIDTH. Being a Manager, it inherits this constant, but its documentation doesn't express that it is a supported state. Your best bet is to rely on the FIXED_SIZE state and calculate the width of each of your columns based on the size of the display (displayWidth / numColumns). Then you can use GridFieldManager#setColumnProperty() to define the fixed width for the columns.
Make sure to take into account the padding applied to the columns and you're good to go.
Hope this helps.
/**
* Shows an example implementation of how to have a GridFieldManager
* sized to the width of the Display.
*/
final class ScreenWidthGridExample extends MainScreen
{
/**
* Number of rows in the grid.
*/
private static final int NUM_ROWS = 1;
/**
* Number of columns in the grid.
*/
private static final int NUM_COLUMNS = 4;
/**
* The grid's column padding.
*/
private static final int COLUMN_PADDING = 5;
/**
* Toggle switch to show the border around the grid.
*/
private static final boolean SHOW_BORDER = true;
/**
* Allocated a new instance of the ScreenWidthGridExample.
*/
ScreenWidthGridExample() {
// Set up the GridFieldManager
GridFieldManager gfm =
new GridFieldManager(NUM_ROWS, NUM_COLUMNS,
GridFieldManager.FIXED_SIZE);
gfm.setColumnPadding(COLUMN_PADDING);
if(SHOW_BORDER) {
gfm.setBorder(BorderFactory.createSimpleBorder(
new XYEdges(0, 0, 0, 0), // top, right, bottom, left
Border.STYLE_DASHED));
}
add(gfm);
// Size the columns of the GridFieldManager. Make sure to calculate
// for the padding applied to the columns.
int columnWidth = (Display.getWidth() / NUM_COLUMNS) -
gfm.getColumnPadding();
for(int i = 0; i < NUM_COLUMNS; i++) {
gfm.setColumnProperty(i, GridFieldManager.FIXED_SIZE, columnWidth);
}
// Populate the columns.
gfm.add(new ButtonField("1", Field.FIELD_HCENTER));
gfm.add(new ButtonField("2", Field.FIELD_HCENTER));
gfm.add(new ButtonField("3", Field.FIELD_HCENTER));
gfm.add(new ButtonField("4", Field.FIELD_HCENTER));
}
}

Blackberry RichTextField preferred height during layout

This is using the Backberry JDK (5.0 if needed).
I have a custom Manager that contains a RichTextField. I want the height of the field to vary by the amount of text in the RichTextField.
The sublayout code looks like this (rtf is a RichTextField object):
protected void sublayout(int width, int height) {
int h = rtf.getPreferredHeight();
setExtent(Display.getWidth(), h);
layoutChild(rtf, Display.getWidth(), h);
setPositionChild(rtf, 0, 0);
setExtent(Display.getWidth(), h);
}
The call to rtf.getPreferredHeight always returns the same value, no matter how much text (and therefore how many lines on the screen).
Any clues on how to get the height of a RichTextField when the content and width are known?
Of course, as soon as I posted it I figured out the answer. Query the control after calling layoutChild.
This fixed it:
int h = rtf.getPreferredHeight();
layoutChild(rtf, Display.getWidth(), h);
h = rtf.getHeight();
setPositionChild(rtf, 0, 0);
setExtent(Display.getWidth(), h);
I would have deleted the question but maybe this will help someone else.
RichTextField deviceId = new RichTextField() {
protected void setExtent(int width, int height) {
super.setExtent(Display.getWidth() - 30, 25);
}
};
This solved my problem for setting height and width for RichTextField when you don't want to write separate class for it.

Resources