| Class | Description |
|---|---|
| ArrayTransformations |
Collections array transformation methods.
|
| ObjectToStringStyle |
A ToStringStyle for objects.
|
| Exception | Description |
|---|---|
| TableException |
Standard exception for ASCII tables.
|
toString() method for 2-dimensional arrays (I didn't find anyone elsewhere) - ArrayTransformations.ARRAY_TO_STRING(Object[][])ArrayTransformations.FLIP_ARRAY(String[][])ArrayTransformations.NORMALISE_ARRAY(int, String[][])ArrayTransformations.WRAP_LINES(int, Object)Let's call a row a line in a table. A table can have multiple (basically any number of ) rows. Let's call a column a part of a row with special formatting. A row can have one or more columns, with each row of a the same table having the same number of columns. Let's call a cell a part of the table identified by row and column. For instance the 2nd column of the 3rd row would be cell 3-2.
Filling a table with content means to add rows with their columns, one row at a time until all rows are added. The tables here provide andaddRow() method with variable argument, checking per table that the number of columns (objects in the argument) is equal per row added.
If all cells fit in the defined (or calculated) width of the columns and tables, nothing special is required.
Here, one can use lists or sets or arrays to represent the rows with their columns and easily render them.
For instance, the following code creates a table with all cells fitting in the calculated width (2 rows with 3 columns each and width of 19):
V2_AsciiTable at = new V2_AsciiTable();
at.addRule();
at.addRow("1-1", "1-2", "1-3");
at.addRule();
at.addRow("2-1", "2-2", "2-3");
at.addRule();
With the rendered output of (using a renderer with the V2_E_TableThemes.UTF_LIGHT theme):
┌─────┬─────┬─────┐
│ 1-1 │ 1-2 │ 1-3 │
├─────┼─────┼─────┤
│ 2-1 │ 2-2 │ 2-3 │
└─────┴─────┴─────┘
However, if only one of the cells is "over-width" this simple approach will not work anymore.
For instance using the following code for the first row will create a problem:
at.addRow("1-1", "1-2 text", "1-3");
The expected rendered table would need to wrap the over size cell 1-2 resulting in the following output:
┌─────┬─────┬─────┐
│ 1-1 │ 1-2 │ 1-3 │
│ │ tex │ │
│ │ t │ │
├─────┼─────┼─────┤
│ 2-1 │ 2-2 │ 2-3 │
└─────┴─────┴─────┘
This means to actually add (for the render process), multiple lines to cells 1-1 and 1-3 to match up with the new added lines in cell 2-2.
Simply using lists or sets or even arrays may (can) result in complicated code.
The approach taken in the ASCII table is to ignore this problem until a table is to be rendered.
Then the methods introduced above come in handy to calculate a 2-dimensional array solving the problem described here (and a few more).
A table is filled as described above: row by row with each row having columns and the content of each column set by an object. When filling a table, nothing is done beside creating an array of objects as columns per row added to the table.
A renderer then sees a table as a set of rows, each of which is an array of objects.
The objects are the content of cells, their respective toString() method being used to create the content.
The renderer also has the width of columns and the overall table width.
Per row, the renderer then creates a 2-dimensional array. In the simple case that all cells fit in the given width, this array will have a width of 3 (3 columns per row) and a length of 1 (nothing done with the cell content) per row.
In the simple case (all cells fit) described above, the renderer will simply create the following content arrays for row 1 (top) and row 2 (bottom):
[0][0]: 1-1
[1][0]: 1-2
[2][0]: 1-3
[0][0]: 2-1
[1][0]: 2-2
[2][0]: 2-3
For the second example above, with an over-size column, the renderer will need to first wrap the contents of cell 1-2 and then normalize the content array of row 1 adding the new lines in cell 1-1 and cell 1-3 to match the new created lines for the wrapped lines in cell 1-2.
To do that, the renderer uses the two array transformation methods
ArrayTransformations.WRAP_LINES(int, Object) to wrap the lines in cell 1-2 and
ArrayTransformations.NORMALISE_ARRAY(int, String[][]) to normalize the cells 1-1 and 1-3.
0 in those added lines means empty line).
Row 2 is the same as for the simple example.
[0][0]: 1-1
[0][1]: 0
[0][2]: 0
[1][0]: 1-2
[1][1]: tex
[1][2]: t
[2][0]: 1-3
[2][1]: 0
[2][2]: 0
[0][0]: 2-1
[1][0]: 2-2
[2][0]: 2-3
Once the renderer has created a content array per row with wrapped lines and normalized cells, the next problem is to create the actual output. As can be seen in the last example above (wrapped lines for cell 1-2), using the originally created array is not very efficient, because the renderer will need complicated nested loops to reach all cells.
However, if we flip the content array (do a horizontal and vertical transformation), we will get a content array that has per first dimension all cells to be printed.
This is what ArrayTransformations.FLIP_ARRAY(String[][]) does.
[0][0]: 1-1
[1][0]: 1-2
[2][0]: 1-3
[0][0]: 2-1
[1][0]: 2-2
[2][0]: 2-3
Flipping these arrays will result in the following:
[0][0]: 1-1
[0][1]: 1-2
[0][2]: 1-3
[0][0]: 2-1
[0][1]: 2-2
[0][2]: 2-3
Now, it is a simple loop throw the arrays first dimension for all printable lines, and a simple loop through the arrays second dimension for all printable cells.
Similar for the over-size example above. The original content arrays looked like this:
[0][0]: 1-1
[0][1]: 0
[0][2]: 0
[1][0]: 1-2
[1][1]: tex
[1][2]: t
[2][0]: 1-3
[2][1]: 0
[2][2]: 0
[0][0]: 2-1
[1][0]: 2-2
[2][0]: 2-3
Fliping the arrays will result in the following arrays for the renderer:
[0][0]: 1-1
[0][1]: 1-2
[0][2]: 1-3
[1][0]: 0
[1][1]: tex
[1][2]: 0
[2][0]: 0
[2][1]: t
[2][2]: 0
[0][0]: 2-1
[0][1]: 2-2
[0][2]: 2-3
RenderUtilities.createContentArray(Object[], int[], int[]).
The method receives the original content array of a row plus an integer array with column width and an integer array with padding per column (V2 introduced padding for columns).
The following code shows how a renderer would call this method:
String[][] ar;
ar = V2_Utilities.createContentArray(new Object[]{"1-1", "1-2 text", "1-3"}, new int[]{5, 5, 5}, new int[]{1, 1, 1});
The method then creates a return array:
String[][] ret = new String[width.length][];
Per entry in the given content array, it then determines if lines have to be wrapped (content of null means column span):
int length = 0;
for(int i=0; i<columns.length; i++){
Object o = columns[i];
if(o==null){
length += width[i];
continue;
}
else{
length += width[i];
}
if(padding[i]>0){
length = length - padding[i]*2;
}
ret[i] = ArrayTransformations.WRAP_LINES(length, o);
length = 0;
}
Once the line wrapping is done, the resulting array can be normalized:
ret = ArrayTransformations.NORMALISE_ARRAY(width.length, ret);
And then finally flipped and returned:
ret = ArrayTransformations.FLIP_ARRAY(ret);
return ret;
toString() methods using StandardToStringStyle.
TableException implements a runtime exception.
This is used in the tables for instance for initialization substituting for more common runtime or illegal argument exceptions.Copyright © 2010–2015. All rights reserved.