Using inbuilt layout managers to display information in a grid is quite simple. Consider the examples in the pictures below. Using Groovy language for demonstration, Figure 1 shows code to display buttons in a linear layout while Figure 2 shows how to display the same buttons in a grid by just adding one line of code - p.setLayout(new GridLayout(3, 4)).
0r1 0r2 0r3 1r0
1r1 1r2 1r3 2r0
2r1 2r2 2r3 3r0
Let us test the method, say 10 times:
We get like the following (note that I have used _ for padding instead for space for better display in this html document)
Figure 1: Displaying buttons using the default Flow layout
Figure 2: Displaying buttons using the Grid layout
It can be that simple. But what if you are using a platform or language that does not come with inbuilt layout managers? Or perhaps you just want to output plain text to the console but it should be formatted in a grid. Or you just want to have more control on how your data is displayed?
Luckily, it is not too difficult but there are a few points to know that are handy. Consider the following grid with 3 rows and 4 columns:
1 2 3 4
5 6 7 8
9 10 11 12
The number of columns is the width of the grid, in this case 4.
If we divide each number by the width we get the following, where r means remainder:
0r1 0r2 0r3 1r0
1r1 1r2 1r3 2r0
2r1 2r2 2r3 3r0
- Each column shares the same remainder!
- The remainder in the last column is zero.
- Except for the last value each number in the same row has the same integer value.
Now suppose we have a similar grid but whose numbering starts from 0
0 1 2 3
4 5 6 7
8 9 10 11
If again we divide each number by the width we get the following, where r means remainder:
0r0 0r1 0r2 0r3
1r0 1r1 1r2 1r3
2r0 2r1 2r2 2r3
Notice that:
- Each column shares the same remainder!
- The remainder in the last column is 3.
- Each number in the same row has the same integer value.
In the first grid we started counting from 1 whereas in the second grid we started from 0. The difference between 1 and 0 is called the offset. Notice the effect in properties numbered 3 for each case. With a little experimentation and more observation we can come up with the following method/function to print a grid
def printGrid(List list, int width){
offset = list.first()
for(i in list){
if((i - offset) % width == 0 && i != start){
println ''
}
print "$i".padLeft(6) //padLeft is just for formatting so the output looks good
}
}
Let us test the method, say 10 times:
random = new Random()
10.times{
offset = random.nextInt(10)
width = random.nextInt(8) + 2
r = random.nextInt(5) + 2
length = width * r -1
list = (offset..length).toList()
println "\n" +"-" * 30
println "List is=$list, width=$width, r=$r"
printGrid(list, width)
}
We get like the following (note that I have used _ for padding instead for space for better display in this html document)
----------------------------------------
List is = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],
width = 8, r = 6
_____4_____5_____6_____7_____8_____9____10____11
____12____13____14____15____16____17____18____19
____20____21____22____23____24____25____26____27
____28____29____30____31____32____33____34____35
____36____37____38____39____40____41____42____43
____44____45____46____47
----------------------------------------
List is = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
width = 8, r = 3
_____3_____4_____5_____6_____7_____8_____9____10
____11____12____13____14____15____16____17____18
____19____20____21____22____23
----------------------------------------
List is = [9, 10, 11, 12, 13, 14, 15], width = 8, r = 2
_____9____10____11____12____13____14____15
----------------------------------------
List is = [5], width = 2, r = 3
_____5
----------------------------------------
List is = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
width = 4, r = 5
_____4_____5_____6_____7
_____8_____9____10____11
____12____13____14____15
____16____17____18____19
----------------------------------------
List is = [8, 9, 10, 11, 12, 13, 14, 15, 16, 17],
width = 9, r = 2
_____8_____9____10____11____12____13____14____15____16
____17
----------------------------------------
List is = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34],
width = 7, r = 5
_____6_____7_____8_____9____10____11____12
____13____14____15____16____17____18____19
____20____21____22____23____24____25____26
____27____28____29____30____31____32____33
____34
----------------------------------------
List is = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26],
width = 9, r = 3
_____2_____3_____4_____5_____6_____7_____8_____9____10
____11____12____13____14____15____16____17____18____19
____20____21____22____23____24____25____26
----------------------------------------
List is = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
width = 7, r = 3
_____0_____1_____2_____3_____4_____5_____6
_____7_____8_____9____10____11____12____13
____14____15____16____17____18____19____20
----------------------------------------
List is = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
width = 8, r = 5
_____6_____7_____8_____9____10____11____12____13
____14____15____16____17____18____19____20____21
____22____23____24____25____26____27____28____29
____30____31____32____33____34____35____36____37
____38____39
So it looks like our method works. Here is the modified version for our html friendly output above
def printGrid(List list, int width){
offset = list.first()
for(i in list){
if((i - offset) % width == 0 && i != start){
println ''
}
print "$i".padLeft(6, '_')
}
}
More to come in Part 2. Thank you.