B4J Tutorial [ABMaterial] My take on the Grid

Hi there

Ok, I'm just a newbie when it comes to ABMaterial, my fourth week now. It's been a wonderful journey and very interesting too.

For a while now I have been struggling to understand the grid, Alian also did explain, my two kidneys in the head didnt register at all. Problem is when it comes to a grid, one thinks of rows and columns not rows and cells and the code to create them looked intimidating to say the least.

So for a while I have avoided them, but then I cant do that forever, I want to know all the ins and outs of the ABMaterial framework and thus cant create beautiful apps if I dont know the grid.

Some time ago Alian did a post about a proof of concept, a grid builder, he talked about an inspiration from "Shoelace for Bootstrap". So I thought, let me google "shoelace for bootstrap".


Blah blah blah blah. So, the ABMaterial grid is based on a bootstrap approach of doing the grid. Ok, I though. So what does Bootstrap say about grids? Offsets, Padding, Sizes, Panning etc.

All this time, the Grids page in the demo was saying the same thing, why couldnt I figure it out then? This has just been infront of my eyes.

Here is how I understand it...

The AddRows.... and AddCells methods are used to create a flexible grid for your page. Personally I wanted to find the diference between AddRows and AddRowsM.

Each Row has some properties, when you are creating one, you are specifying these are variables...


Ok, what does AddRows mean?

AddRows just as explained in the demo add rows to your grid. You specify the number of Rows, whether the rows should be centered on the page and pass a theme to use. The default margins for Top and Bottom are set to be 20px, however AddRows sets your TopMargin to 0 and BottomMargin to 20px.

So AddRows(10, True, "lightblue") will add 10 rows centered on the page with a TopMargin of 0 and BottomMargin of 20px with a lighblue theme.

AddRows(numberOfRows, centerInRow, themeName)


Licensed User
Next, AddRowsM

With AddRowsM, you are provided an option to set your margins, thus the M at the end of it all. As you might have noted, AddRowsM definition is

AddRowsM(int numberOfRows, boolean centerInPage, int marginTopPx, int marginBottomPx, String themeName)

So the difference with the previous AddRows is that here you need to specify the M-argins, the Top and Bottom margins. Common sense is not always common hey... So I guess you are getting clearer of the OSMP? Ok, let me not get ahead of myself. With AddRowsM you thus specify all the Row properties. Let's go On.


Licensed User
Next, let's look at the AddCells methods. For a moment, think of the "cell" as a "column". Please note going forward I will refer to a cell as a column. That's how my mind wants to deal with this.

Figure 1


So, each row can have 12 columns with the same size no matter what device you use. Fine. Perfect.

Now what do all these zeros, sized or 12 mean?

If you look at the last methods in the grid demo, its AddCellOS, its supposed to be AddCellOSMP. See the param column, that indicated the properties of each column.


As you have noted, some properties here have Small, Medium and Large. These are device specific. I will explain.

There are four methods to add columns to each row, AddCells12, AddCellsOSMP, AddCellsOS, AddCells12MP.

I think the most used method in the demo is AddCells12, anyway. I will start with AddCellsOSMP as its the master method where you indicate all the properties for the columns you are adding.


With AddCellsOSMP, you are adding columns to the row but you specify the O-offsets, S-ize, M-argins and P-adding for each column

AddCellsOSMP(int numberOfCells, int offsetSmall, int offsetMedium, int offsetLarge, int sizeSmall, int sizeMedium, int sizeLarge, int marginTopPx, int marginBottomPx, int paddingLeftPx, int paddingRightPx, String themeName)

This in essence, one needs to specify all the values for each property of the column. Now please think of the S-ize as S-pan for a moment, that's how my mind is wanting to deal with this. Please note that going forward, any reference to Size will mean Span (i.e. how many spaces to take)

Now, lets look at the ...Small, ...Medium, ...Large ending properties. When creating columns in each row you need to think in terms of the 3 devices provided and how each row and column will look like. Ok, let's take a break...


Licensed User
Like I was saying, AddCellsOSMP, you are adding columns to a row and specifying all the variable definitions per each column, all for 3 devices at the same time.

Really? Really. All the Small, Medium, Large properties are relating to the devices.

SizeSmall (SpanSmall as I want to call it) tells the framework how much should the column span in small devices
SizeMedium (SpanMedium as I want to call it) tells the framework how much should the column span in medium devices
SizeLarge (SpanLarge as I want to call it) tells the framework how much should the column span in large devices.

Figure 1


In the above Figure 1, all the values with ? (question mark) you specify the values as the rest are default)

Let's look at the image here an each definition of the methods.

AddCells12(int numberOfCells, String themeName)

Add 1 row with a number of columns that spans 12 equal spaces in each device.

AddCells12MP(int numberOfCells, int marginTopPx, int marginBottomPx, int paddingLeftPx, int paddingRightPx, String themeName)

For this method, you specify the M-argins an P-adding, however the span of each column will be 12 still.

AddCellsOS(int numberOfCells, int offsetSmall, int offsetMedium, int offsetLarge, int sizeSmall, int sizeMedium, int sizeLarge, String themeName)

With AddCellsOS, you specify the O-ffset and S-izes (S-pan) for each column added. Perhaps reading this method in groups of 3 will be better.

AddCellsOS is passed the number of columns to create then 2 groups of data for the offset and size for 3 devices

e.g. AddCellsOS(1,0,0,0,6,6,6)

First Group

O(S) - Offset Small
O(M) - Offset Medium
O(L) - Offset for Large Devices

translates to 0,0,0

Second group
S(S) - Sise Small
S(M) - Size Medium
S(L) - Size Large

also translating to 6,6,6, meaning add 1 column that spans 6 spaces each, no gaps.

And finally

AddCellsOSMP(int numberOfCells, int offsetSmall, int offsetMedium, int offsetLarge, int sizeSmall, int sizeMedium, int sizeLarge, int marginTopPx, int marginBottomPx, int paddingLeftPx, int paddingRightPx, String themeName)

With AddCellsOSMP you specify everything about the cell, O-ffset, S-ize (S-pan), M-argins, P-adding

As explained, Offset creates gaps between the columns.

When I read about Bootstrap, this is what I got.

  • Columns create gaps between column content via Padding/Columns have horizonal padding to create gutters between individual columns
  • There are 12 available columns you wish to Span
  • Offsets move columns to the right by a number
  • Grid columns are created by specifying the number of 12 available columns you wish to span
  • There are 3 tiers, Small, Medium and Large for devices
Last edited:


Licensed User
It's time we looked in the demo grid demo and try and explain what is happening, perhaps I can shed some light that I also found yesterday, which was infront of me all this time... If you have trouble please refer to the Excel Sheet above.

' create the page grid
    page.AddRows(1,True, "").AddCells12(1,"")   
    page.AddRowsM(1,True,0,0, "").AddCellsOS(12,0,0,0,1,1,1,"")
    page.AddRows(3,True, "").AddCells12(1,"")
    page.AddRowsM(1,True,0,0, "").AddCellsOS(2,0,0,0,6,6,6,"")
    page.AddRows(2,True, "").AddCells12(1,"")
    page.AddRowsM(1,True,0,0, "").AddCellsOS(1,6,6,6,6,6,6,"")
    page.AddRows(6,True, "").AddCells12(1,"")

Above is the grid example and it has been explained in the demo, let me try and also explain it in terms of how I see it.

Remember: Offset - gap between columns, MarginTop - top margin of the cell, MarginBottom - bottom margin of the cell, Size - number of spaces to span.

Let go each line bit by bit.

page.AddRows(1,True, "").AddCells12(1,"")

Add 1 row with a 1 column that spans 12 spaces of equal length in all devices. The row should be centered on the page i.e. True


I will also try and explain this using Excel. In the row, 1 column spaning 12 spaces is created, so all spaces will be taken, think of it as "merged".


page.AddRowsM(1,True,0,0, "").AddCellsOS(12,0,0,0,1,1,1,"")

Here we need to specify the margins per device.


The columns in this stance are not merged, each column stands by itself.


As you might have noted, the definitions always start with small, then medium, then large for all properties whether offset, size, margin, padding.

Here we are adding a single row, that is centered on the page with 0 top and bottom margins. In the row we add 12 columns (AddCellsOS(12, we dont want any 'gaps' between the columns, this 0,0,0 for offsets for small, medium and large devices and each column should span 1 space each, 1,1,1, no theme should be applied. As indicated here, we have to specify OS (Offsets and Sizes / Span)

page.AddRows(3,True, "").AddCells12(1,"")


This one adds 3 rows that are centered on the page, the top margin is 0px with a bottom margin of 20px, then in the row add 1 column that spans 12 spaces each for all devices. With excel..., 3 rows per device taking with a 12 area span.


page.AddRowsM(1,True,0,0, "").AddCellsOS(2,0,0,0,6,6,6,"")

Add a single row with 0 top margin and 0 bottom margin. Add 2 columns (AddCellsOS(2, there should be no gaps between the columns, each column should span 6 spaces across all devices.


I will use Excel to demonstrate this, thanks to Alian for his inbox.. All the


Two columns, each with a span of 6 spaces each.

page.AddRows(2,True, "").AddCells12(1,"") : I will skip this, I think you understand now.


page.AddRowsM(1,True,0,0, "").AddCellsOS(1,6,6,6,6,6,6,"")

Add a single row, centered on the page with 0 top margin and 0 bottom margin, within the row, add a single column (AddCellsOS(1, here we need to specify the Offsets and Sizes (Spans) for each column. Each column should have 6 gaps and should span 6 spaces per device.



With this one, the second part of the column is used as the other part was offset 6 spaces each per device. That covers it.


Active Member
Licensed User

Please, write help for CellR method too, because is indocumented.



Licensed User
ABMaterial: page.DebugPrintGrid (Wooooowwww!)


I have just recently ran into one of the page methods, DebugPrintGrid. So after I fired the Demo and just wrote this statement after the build grid line for the GridsPage, I didnt even have to fire the web app to show me the output in the logs. So I decided to play around again and "grid" all the methods of the GridsPage in Excel.

I hope this also helps in explaining this complex grid problem too...
As explained, each row has 12 colums, C1 to C12 below. I will use the GridPage demo methods again here. When you add all the numbers after each AddRows and AddRowsM, you have 15, this means we will have more or less 15 rows, these will be R1 to R15.

Figure 1


So the grid as earlier explained is like a two-dimensional array with Rows and Cells (aka Columns). From this example,

1. 1 row was added with 12 merged columns using AddCells12, this creates a reference of R1C1 in the grid
2. 1 row was added with 12 columns individually, so we have R2C1 to R2C12
3. 3 rows were added with 12 merged columns using AddCells12, so we have R3C1, R4C1 and R5C1. So far we have 5 rows
4. 1 row was added with 2 columns, each with a pan of 6 equal spaces, this made R6C1 and R6C2
5. Then 2 rows were added with 12 columns merged, R7C1 and R8C1
6. Then 1 row was added, padded 6 spaces and 6 pieces wide, resulting in R9C1
7. Then 6 rows were added with 12 merged columns each, resulting in R10-R15(C1)

Hope this addes some more clarity. I think from this its just going to be better to design the grids on paper first then translate to the page methods whilst awaiting for @alwaysbusy grid designer. This is awesome!


Licensed User
A little bit of complexity in the grid.... let me try and explain

Well, if we apply the same principles of what we have understood so far, I guess in more complex grid definitions we will be able to understand it. In the demo, I noted some examples where there were more than 1 call to the AddCells for the same row.

This is in the CompImagePage of the demo...

page.AddRows(1,True, "").AddCellsOS(1,0,0,0,12,4,4,"").AddCellsOS(1,0,1,1,0,7,7,"")

page.AddRows(1,True, "") - adds 1 row to the grid


In that row add 1 column, with zero offsets across all devices but then, for small devices, the column should span across 12 spaces, on medium and large devices span 4 spaces (what happens to the other 8 columns??) Look at the second AddCellsOS call...

So another column is added in the same row, but because the column already has taken 12 spaces for small devices, the next size is zero 0.
For medium and large devices, the first column spanned 4 spaces, the second column was moved 1 space to the right and 7 more spaces added = 12 in total (4+1+7)

Figure 1


For small devices, due to the column being outside the 12 column bracket, any contents written on R6C2 will be wrapped in the next line.
Last edited:


Licensed User
Concluding my take on the Grid...

So, we have a definition of the grid with the first line being...

page.AddRows(1,True, "").AddCells12(1,"")

But then we have noted on the examples that there are multiple, page.Cell(1,1).AddComponent( blah blah blah), so what happens?

This also nearly confused me, as an example, the grid demo example has...

page.Cell(1,1).AddComponent(ABMShared.BuildHeader(page,"hdr1", "Introduction"))
    ' add paragraph   
    page.Cell(1,1).AddComponent(ABMShared.BuildParagraph(page,"par1","Take a look at this section to quickly understand how grids work! Make sure you have read the Themes topic first. We use themes when we design a grid. {B}It is very important you grab the concept of the Grid and Cells before proceeding with the next chapters!{/B}") )
    ' add sub header
    page.Cell(1,1).AddComponent(ABMShared.BuildSubHeader(page, "shdr1", "12 Cells"))

This basically means the content will be added in the R1C1 location and will be appended at that position. I took the liberty of doing this example but only with a few items and turned ShowGridInfo on. As you will note, what I did in excel before here is beautifully done by the ABMaterial framework brilliantly. This is magic!!

Figure 1


All of this is based on the GridDemo grid definition of...

page.AddRows(1,True, "").AddCells12(1,"")   
    page.AddRowsM(1,True,0,0, "").AddCellsOS(12,0,0,0,1,1,1,"")
    page.AddRows(3,True, "").AddCells12(1,"")
    page.AddRowsM(1,True, 0, 0, "").AddCellsOS(2,0,0,0,6,6,6,"")
    page.AddRows(2,True, "").AddCells12(1,"")
    page.AddRowsM(1,True,0,0, "").AddCellsOS(1,6,6,6,6,6,6,"")


That's all folks. As earlier indicated I'm still a newbie with this framework, should you have questions please speak to THEE MAN.


Licensed User
I personally always use the cellR methods. It is easier if you want to 'insert' like a row of cell later and you do not have to move everything which was already in the rows/cells after.
This is often my issue... I need to insert a row, with different format and have to renumber everything following. Where (how) is this easier? My brain is probaly numb from the cold.

Oh btw, back from camping, coding and promotions tour. It was getting a bit chilly out there in the wilds of Western Canada for the past three weeks.