Add: ASCII TABLE JAVA DOC

This commit is contained in:
rubenpirreram
2026-05-04 13:00:06 +02:00
parent 04b61a8cb2
commit 76d236f5f1
@@ -1,43 +1,112 @@
package it.polimi.ingsw.gc14.View.TUI;
import java.util.*;
//TODO javadoc
// Helper generale per costruire tabelle ASCII
/**
* General-purpose helper for building fixed-width ASCII/Unicode tables in a TUI.
*
* <p>A table is built by adding rows one at a time, then calling {@link #build()}
* to obtain the fully rendered string. Column width is computed automatically
* from the widest cell across all rows.
*
* <p>Example usage:
* <pre>{@code
* AsciiTable table = new AsciiTable(BorderStyle.UNICODE, 3);
* table.addHeader("Name", "Food", "PP");
* table.addRow("Alice", "4", "12");
* table.addRow("Bob", "2", "8");
* System.out.println(table.build());
* }</pre>
*/
public class AsciiTable {
//TODO javadoc
/**
* The border style used to draw the table (e.g. Unicode box-drawing,
* plain ASCII, rounded corners).
*/
private final BorderStyle s;
//TODO javadoc
/**
* The number of columns in the table.
* Every row added via {@link #addRow} must contain exactly this many cells.
*/
private final int cols;
//TODO javadoc
/**
* The rows of the table, each represented as a list of cell strings.
* Rows are stored in display order; {@link #addHeader} inserts at index 0.
*/
private final List<List<String>> rows = new ArrayList<>();
//TODO javadoc
/**
* Row indices after which a horizontal separator line is drawn.
* Populated by {@link #addHeader} and {@link #addSeparator}.
*/
private final List<Integer> separators = new ArrayList<>();
//TODO javadoc
/**
* Constructs an empty {@code AsciiTable} with the given border style
* and column count.
*
* @param s the {@link BorderStyle} to use for box-drawing characters
* @param cols the number of columns; every row must supply exactly this
* many cells
*/
public AsciiTable(BorderStyle s, int cols) {
this.s = s; this.cols = cols;
}
//TODO javadoc
/**
* Appends a row at the bottom of the table.
*
* @param cells one string per column, in left-to-right order
*/
public void addRow(String... cells) { rows.add(Arrays.asList(cells)); }
//TODO javadoc
/**
* Appends a row at the bottom of the table.
*
* @param cells a list of strings, one per column, in left-to-right order
*/
public void addRow(List<String> cells) { rows.add(cells); }
//TODO javadoc
public void addHeader(String... cells) { rows.add(0, Arrays.asList(cells)); separators.add(0); }
/**
* Inserts a header row at the top of the table and marks it with a
* horizontal separator so that a dividing line is drawn below it.
*
* <p>Calling this method after rows have already been added will push
* all existing rows down by one position.
*
* @param cells one string per column, in left-to-right order
*/
public void addHeader(String... cells) {
rows.add(0, Arrays.asList(cells));
separators.add(0);
}
//TODO javadoc
public void addSeparator() { separators.add(rows.size()-1); }
/**
* Marks the current last row so that a horizontal separator line is
* drawn below it when the table is built.
*
* <p>Call this method immediately after the row that should be followed
* by the separator.
*/
public void addSeparator() { separators.add(rows.size() - 1); }
//TODO javadoc
/**
* Renders the table to a multi-line string.
*
* <p>Column width is determined dynamically as the length of the longest
* cell across all rows, plus one padding space. All cells are left-aligned
* and padded or truncated to the same width.
*
* @return the fully rendered table as a single string with embedded newlines
*/
public String build() {
var sb = new StringBuilder();
int maxWidth = rows.stream().mapToInt(x->x.stream().mapToInt(y->y.length()).max().getAsInt()).max().getAsInt()+1;
sb.append(hline(s.tl(), s.mt(), s.tr(),maxWidth)).append('\n');
int maxWidth = rows.stream()
.mapToInt(x -> x.stream().mapToInt(y -> y.length()).max().getAsInt())
.max().getAsInt() + 1;
sb.append(hline(s.tl(), s.mt(), s.tr(), maxWidth)).append('\n');
for (int i = 0; i < rows.size(); i++) {
sb.append(s.v());
@@ -45,14 +114,23 @@ public class AsciiTable {
sb.append(rpad(" " + cell, maxWidth)).append(s.v());
sb.append('\n');
if (separators.contains(i) && i < rows.size() - 1)
sb.append(hline(s.sl(), s.sx(), s.sr(),maxWidth)).append('\n');
sb.append(hline(s.sl(), s.sx(), s.sr(), maxWidth)).append('\n');
}
sb.append(hline(s.bl(), s.mb(), s.br(), maxWidth));
return sb.toString();
}
//TODO javadoc
private String hline(String l, String m, String r,int maxWidth) {
/**
* Builds a single horizontal border line spanning all columns.
*
* @param l the left-end character (e.g. {@code ╔}, {@code ╠}, {@code ╚})
* @param m the column-junction character (e.g. {@code ╦}, {@code ╬}, {@code ╩})
* @param r the right-end character (e.g. {@code ╗}, {@code ╣}, {@code ╝})
* @param maxWidth the width in characters of each column segment,
* filled with the horizontal line character of the current style
* @return the rendered horizontal line as a string
*/
private String hline(String l, String m, String r, int maxWidth) {
var sb = new StringBuilder(l);
for (int i = 0; i < cols; i++) {
sb.append(s.h().repeat(maxWidth));
@@ -61,13 +139,40 @@ public class AsciiTable {
return sb.append(r).toString();
}
//TODO javadoc
/**
* Right-pads a string with spaces to the given width, or truncates it
* if it exceeds that width.
*
* @param s the input string
* @param w the desired output width in characters
* @return a string of exactly {@code w} characters
*/
private static String rpad(String s, int w) {
if (s.length() >= w) return s.substring(0, w);
return s + " ".repeat(w - s.length());
}
//TODO javadoc
/**
* Places two pre-rendered text blocks side by side, separated by a gap.
*
* <p>Each block is a list of lines as returned by {@link #build()}.
* Lines in the left block are padded to a uniform width so that the
* right block always starts at the same horizontal position. If one
* block is taller than the other, the shorter one is padded with blank
* lines.
*
* <p>Example:
* <pre>{@code
* List<String> left = Arrays.asList(table1.build().split("\n"));
* List<String> right = Arrays.asList(table2.build().split("\n"));
* System.out.print(AsciiTable.sideBySide(left, right, 2));
* }</pre>
*
* @param left lines of the left block
* @param right lines of the right block
* @param gap number of blank spaces between the two blocks
* @return the merged string with embedded newlines
*/
public static String sideBySide(List<String> left, List<String> right, int gap) {
int leftWidth = left.stream().mapToInt(String::length).max().orElse(0);
int maxHeight = Math.max(left.size(), right.size());
@@ -75,17 +180,11 @@ public class AsciiTable {
var sb = new StringBuilder();
for (int i = 0; i < maxHeight; i++) {
String l = i < left.size()
? left.get(i)
: " ".repeat(leftWidth);
// padda la riga sinistra se è più corta delle altre
String l = i < left.size() ? left.get(i) : " ".repeat(leftWidth);
l = rpad(l, leftWidth);
String r = i < right.size() ? right.get(i) : "";
sb.append(l).append(padding).append(r).append('\n');
}
return sb.toString();
}
}