Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Create a custom layout manager for a screen

by Retired ‎02-12-2010 04:04 PM - edited ‎09-16-2010 03:45 PM (15,538 Views)

Summary

 

This article applies to the following:

  • BlackBerry® Java Development Environment (JDE)
  • BlackBerry Wireless Handhelds™ based on Java™

Procedure

 

You can create your own custom layout manager by extending the net.rim.device.api.ui.Manager class and customizing it to fit your needs. Custom layout managers enable you to customize the placement of fields on the screen and customize navigation within these fields. To do this, you need to implement at least the following three methods:

  1. public int getPreferredWidth()

    This method returns the manager's preferred width.


  2. public int getPreferredHeight()

    This method returns the manager's preferred height.


  3. public void sublayout(int height, int width)

    This method is invoked by the manager's layout() method and instructs each child field how and where to be laid out.

This can be accomplished by calling Manager.setPositionChild(Field field, int x, int y) and LayoutChild(Field field, int width, int height) for each field contained in the manager.

 

Here is an example of how a screen can associate itself with a custom layout manager:

 

 

/*********************
Layout Manager
*********************/
class LayoutManager extends Manager {
public LayoutManager() {
//construct a manager with vertical scrolling
super(Manager.VERTICAL_SCROLL);
}
//overwrite the nextFocus method for custom navigation
protected int nextFocus(int direction, boolean alt) {
//retrieve the index of the current field that is selected
int index= this.getFieldWithFocusIndex();
if(alt) {
if(direction 0){...}
else{...}
}
// if we did not handle it, let the manager's parent class
if (index == this.getFieldWithFocusIndex())
return super.nextFocus(direction, alt);
else
return index;
}
protected void sublayout(int width, int height) {
Field field;
//get total number of fields within this manager
int numberOfFields = getFieldCount();
int x = 0;
int y = 0;
for (int i = 0;i < numberOfFields;i++) {
field = getField(i); //get the field
setPositionChild(field,x,y); //set the position for the field
layoutChild(field, width, height); //lay out the field
y += ...;
...
}
setExtent(width, height);
}
public int getPreferredWidth() {
return 160;
}
public int getPreferredHeight() {
int height= 0;
int numberOfFields= getFieldCount();
for (int i= 0; i < numberOfFields; i++) {
height+= getField(i).getPreferredHeight();
return height;
}
}
/****************
Main Class
****************/
...
RichTextField myField = new RichTextField("Hello");
RichTextField myOtherField = new RichTextField("World");
LayoutManager myManager = new LayoutManager();
MainScreen myScreen = new MainScreen();
myScreen.add(myManager);
myManager.add(myField);
myManager.add(myOtherField);
...

 

 


Additional Information

 

Contributors
Comments
by Developer
on ‎11-10-2010 10:44 AM

This article needs an update badly. A good developer will find his way through even with this just giving ideas, but it would be more helpful to have some clearer code.  Here are some points which I personally disliked:

 

nextFocus(int, boolean) has been deprecated since OS 5.0.  The code in it is just plain wrong (what's "if (direction 0)" again?) and shows none of the ideas for custom implementation of this particular method. Some comments on what is the good approach (at least) are necessary.

 

Width and height passed to layoutChild need to be adjusted for each subsequent child (width - x, height - y at least).

 

setExtent(width, height) is almost criminal - the example below adds it to the default MainScreen() which gives its children the height of (Integer.MAX_VALUE >> 1). Even if the fields in this Manager all fit on the screen, there will be scrolling "arrows" (and touchscreen devices will be able to scroll away everything). Give at least some ideas on calculating the actual width and height and setting them (unless USE_ALL_WIDTH and/or USE_ALL_HEIGHT are specified, which the code can explicitly address with isStyle(...) checks).

 

This article would be a great place to introduce the developers to the concept of virtual extent - something along the lines of:

int availableWidth = width;

if (isStyle(HORIZONTAL_SCROLL)) {

  availableWidth = Integer.MAX_VALUE >> 1;

}

// same with availableHeight

...

int totalWidth = 0;

int totalHeight = 0;

// calculate totalWidth / totalHeight as we lay out the children

...

// at the end

setExtent(Math.min(width, totalWidth), Math.min(height, totalHeight));

setVirtualExtent(totalWidth, totalHeight);

 

There are more points, but the above are the most obvious.

Users Online
Currently online: 26 members 1,806 guests
Please welcome our newest community members: