Connecting Groups
Back to SiteGroups!

SpringSters - Blogging Bunch

We think therefore we are

Layout Management in J2ME

One day Anuj (Our Product Boss :)) came to me with some layouts and asked to support all of the following layouts in J2ME application.

Layout
All these layouts are combinations of images and strings. Initially, I was worried about the implementation, but after going through the layouts couple of times, I thought Gridbag layout of swings would support all these combinations. I knew how Gridbag worked but didn’t know how I could arrange components in horizontal and vertical cells. The most challenging issue was J2ME’s memory limitations for both jar and jad. We can develop a full fledged Gridbag layout class just like swing but some issues could arise.

  • Potential big class size
  • We will have to keep minimum instances of components for heap issues, the best case being one instance per component.

So let’s start engineering with minimum requirement of arranging cells.

    Here is the list of items which we need to consider while adding components in layout:

  • Starting horizontal cell
  • Starting vertical cell
  • Number of horizontal cells required
  • Number of vertical cells required
  • Component

All these will go as parameters in the add method.
add(component, start_horizontal_cell, start_vert_cell, no_of_horizontal_cell, no_of_vert_cell)

To store these components, we can have an array of components or some custom defined array list.
Each cell will have some height and width say CellH =20 and CellW = 20.

Thats all.. we are ready to construct a layout class which will hold images and strings.
Say we have two UI classes for rendering a single image MyImage and a single string as label MyLabel.

Here is the code piece for our layout class. We are considering this layout class itself as a component which will make it easy for us to add it to a container.

/**
* A class which can hold any component, which can be rendered at any position
* in this component’s boundary depending upon its cell location.
* This is a Gridbag layout. To create a label of this type with any
* component,
* e.g to add MyLabel at cell position row 0, column 0 with
* 2 horizontal cells and 1 vertical cell,
*
* TestLabel label = new TestLabel();
* myCanvas.addComponent(label);
* MLabel strLabel = new MLabel(”First label”);
* label.add(strLabel, (byte)0, (byte)0, (byte)2, (byte)0);
*/
public class TestLayout extends Component{

private MyArrayList components; //user defined array list
public int cellW = 20;
public int cellH = 20;
public int noOfRowCells;
public int noOfColumnCells;
public boolean showGrid;

/**
* Creates a new instance of TestLabel
* @Param boolean tells whether this Label will should have
* canvas width or width that is neccesary to component
*/
public TestLabel() {
height = 20;
width = canvasW;
components = new MArrayList();
calculateDimensions();
isStatic = false;
}

/**
* this method renders component
* @param Graphics
**/
protected void renderComponent(Graphics g) {
int posX = compX;
int posY = compY;
int size = components.size();
g.setColor(MMasterColors.GREY);
if(showGrid){
for(int i = 0; i < noOfRowCells ; i ++){
g.drawLine(compX, posY, width, posY);
posY += cellH;
}
g.drawLine(compX, posY, width, posY);
for(int i = 0; i < noOfColumnCells ; i ++){
g.drawLine(posX, compY, posX, compY + height);
posX += cellW;
}
}
for(int i = 0; i < size ; i ++){
((MComponent)components.get(i)).renderComponent(g);
}
}

/**
* This method calculates dimensions
**/
protected void calculateDimensions() {
noOfColumnCells = width / cellW;
noOfRowCells = height / cellH;
}

/**
* A method to add component to AdvLabel
* @param MComponent component which is to be added
* @Param byte rowNo cell at row level
* @Param byte Columno cell at Column level
* @Param byte no of horizontal rows required
* @Param byte no of vertical rows required
* @param byte alignment
**/
public void addComponent(MComponent comp, byte rowNo, byte ColumnNo, byte noOfHoriCells, byte noOfVertCells){
components.add(comp);
if(height < ((ColumnNo + noOfVertCells) * cellH))// setting height if needed
height = (ColumnNo + noOfVertCells) * cellH;
calculateDimensions();
int tempX = 0;
int tempY = 0;
tempX = compX + ((rowNo * cellW) + (((noOfHoriCells * cellW) - comp.getComponentWidth()) / 2));
tempY = compY + (((((noOfVertCells * cellH) - comp.getComponentHeight())/ 2) + (ColumnNo * cellH)));
comp.setComponentXY(tempX, tempY);
}
}

public class Component{

public int componentX;
public int componentY;
protected int height;
protected int width = canvasW;

protected void renderComponent(Graphics g) {
}

protected void calculateDimensions() {
}

/**
*Mutator method to set x, y positions
*@param x X co-ordinate
*@param y Y co-ordinate
*/
public void setComponentXY(int x, int y) {
componentX = x;
componentY = y;
}

/**
*returns component height
*@return height
*/
public int getComponentHeight() {
return height;
}

public int getComponentWidth() {
return width;
}
}

Above code is at very primary level which will fulfill our requirement of arranging components in a grid. We can then add (if memory permits :-) ) advanced features like:

  • Providing key navigations
  • Maintaining and highlighting current component
  • Aligning components within the mentioned cells
  • Providing more ui specific things like borders, background colors etc.
  • and so on….

©2007 - 2008 MangoSpring. All Rights Reserved.