Basically, for each column, you need some kind of list (either an array or preferably an List
). You also need to maintain information on each columns max-width (I typically put this in another List
).
You need to loop each line, breaking to down into it's column elements and place each element in the corresponding column List
. You should also be calculating the width requirements for each column as you go.
Once you have this all structured out, you need to then reconstruct the out put, using something like a StringBuilder
to rebuild each line of the output but so that each column has the required additional spacing to allow the columns to flow.
Updated with example
Now, normally, I would store each row as an individual object, as it makes it easier to maintain a consistent idea of the total number of rows, but, using you code as a jumping off point...
import java.text.NumberFormat;
public class TestTextColumnFormatting {
public static void main(String[] args) {
String[] myNameArray = new String[]{
"Mr. Samete",
"Ms. Torbura",
"Mr. Perem",
"Mr. Rothaw",
"Miss. Endemos",
"Mr. Chomoshon",
"Mrs. Aldir",};
double[] stipends = new double[]{
500,
200,
300,
1000,
250,
125,
600,
338
};
NumberFormat nf = NumberFormat.getCurrencyInstance();
double tally = 0;
int columnWidths[] = new int[2];
for (int index = 0; index < myNameArray.length; index++) {
columnWidths[0] = Math.max(columnWidths[0], myNameArray[index].length());
columnWidths[1] = Math.max(columnWidths[1], nf.format(stipends[index]).length());
tally += stipends[index];
}
columnWidths[1] = Math.max(columnWidths[1], nf.format(tally).length());
StringBuilder sb = new StringBuilder(128);
for (int index = 0; index < myNameArray.length; index++) {
String name = myNameArray[index];
String stipend = nf.format(stipends[index]);
sb.append(name).append(fill(name, columnWidths[0], ' ')).append(" ");
sb.append(fill(stipend, columnWidths[1], ' ')).append(stipend);
sb.append("
");
}
sb.append(fill("", columnWidths[0], ' ')).append(" ");
sb.append(fill("", columnWidths[1], '=')).append("
");
sb.append(fill("", columnWidths[0], ' ')).append(" ");
sb.append(fill(nf.format(tally), columnWidths[1], ' ')).append(nf.format(tally));
sb.append("
");
System.out.println(sb.toString());
}
public static String fill(String sValue, int iMinLength, char with) {
StringBuilder filled = new StringBuilder(iMinLength);
while (filled.length() < iMinLength - sValue.length()) {
filled.append(with);
}
return filled.toString();
}
}
This will then output something like...
Mr. Samete $500.00
Ms. Torbura $200.00
Mr. Perem $300.00
Mr. Rothaw $1,000.00
Miss. Endemos $250.00
Mr. Chomoshon $125.00
Mrs. Aldir $600.00
=========
$2,975.00
Updated
I'm such an idiot, I just realised that you're using a JOptionPane
:P
The simplest solution would be to construct a HTML table and let Swing render it for you...
import java.text.NumberFormat;
import javax.swing.JOptionPane;
public class TestTextColumnFormatting {
public static void main(String[] args) {
String[] myNameArray = new String[]{
"Mr. Samete",
"Ms. Torbura",
"Mr. Perem",
"Mr. Rothaw",
"Miss. Endemos",
"Mr. Chomoshon",
"Mrs. Aldir",};
double[] stipends = new double[]{
500,
200,
300,
1000,
250,
125,
600,
338
};
NumberFormat nf = NumberFormat.getCurrencyInstance();
double tally = 0;
StringBuilder sb = new StringBuilder(128);
sb.append("<html><table border='0'>");
for (int index = 0; index < myNameArray.length; index++) {
String name = myNameArray[index];
String stipend = nf.format(stipends[index]);
sb.append("<tr><td align='left'>");
sb.append(name);
sb.append("</td><td align='right'>");
sb.append(stipend);
sb.append("</td></tr>");
tally += stipends[index];
}
sb.append("<tr><td align='center'>");
sb.append("</td><td align='right'>");
sb.append(nf.format(tally));
sb.append("</td></tr>");
JOptionPane.showMessageDialog(null, sb.toString());
}
}