23

I need to display a list of items with their prices from an array and would like to align the prices. I almost have it working but needs improvements. Below is the code and the output. Any ideas how to make all prices aligned? So far some work but some don't.

//for loop
System.out.printf("%d. %s \t\t $%.2f\n",
                i + 1, BOOK_TYPE[i], COST[i]);

output:

1. Newspaper         $1.00
2. Paper Back        $7.50
3. Hardcover book        $10.00
4. Electronic book       $2.00
5. Magazine          $3.00
starball
  • 20,030
  • 7
  • 43
  • 238
user1781482
  • 623
  • 3
  • 15
  • 24
  • http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html shows how you can align your output. For example: formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E); where 10 is the number of "spaces" between the equal sign and the number being printed and 4 is the number of decimal places. – Nico Apr 12 '13 at 00:33

5 Answers5

38

You can try the below example. Do use '-' before the width to ensure left indentation. By default they will be right indented; which may not suit your purpose.

System.out.printf("%2d. %-20s $%.2f%n",  i + 1, BOOK_TYPE[i], COST[i]);

Format String Syntax: http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax

Formatting Numeric Print Output: https://docs.oracle.com/javase/tutorial/java/data/numberformat.html

PS: This could go as a comment to DwB's answer, but i still don't have permissions to comment and so answering it.

Nolequen
  • 3,032
  • 6
  • 36
  • 55
LionsDen
  • 583
  • 6
  • 13
4

A simple solution that springs to mind is to have a String block of spaces:

String indent = "                  "; // 20 spaces.

When printing out a string, compute the actual indent and add it to the end:

String output = "Newspaper";
output += indent.substring(0, indent.length - output.length);

This will mediate the number of spaces to the string, and put them all in the same column.

christopher
  • 26,815
  • 5
  • 55
  • 89
  • Seeing answers like this makes me wish Java's `String` had `padLeft`, `padRight`, etc like other programming languages' standard libraries... – Patashu Apr 12 '13 at 00:37
  • 2
    Java does have StringUtils.leftPad() and StringUtils.rightPad(). these are part of Apache Commons Lang. – DwB Apr 12 '13 at 00:40
4

Format specifications for printf and printf-like methods take an optional width parameter.

System.out.printf( "%10d. %25s $%25.2f\n",
                   i + 1, BOOK_TYPE[i], COST[i] );

Adjust widths to desired values.

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
DwB
  • 37,124
  • 11
  • 56
  • 82
  • 17
    First off, don't call someone lazy without know anything about that person. Second, I am a Java beginner but I did read about printf and I know the %10d will print 10 spaces before the variable. Now Mr. Know-it-all-and-not-lazy, your code is nowhere near what I need. If you read my question, I need to have left alignment, except the space after the second variable needs to change (not constant) so the third variable is also aligned. Thanks anyways. Good day. – user1781482 Apr 12 '13 at 00:46
  • 2
    if you had read the printf docs then you would know that %10d specifies a field width of 10 and %010d specifies zero left padded field with width 10. consider reading the docs. – DwB Apr 12 '13 at 01:00
  • 2
    reading the docs will show you that a - as a flag will left justify the field. ex %-10d – DwB Apr 12 '13 at 01:02
2

Here's a potential solution that will set the width of the bookType column (i.e. format of the bookTypes value) based on the longest bookTypes value.

public class Test {
    public static void main(String[] args) {
        String[] bookTypes = { "Newspaper", "Paper Back", "Hardcover book", "Electronic book", "Magazine" };
        double[] costs = { 1.0, 7.5, 10.0, 2.0, 3.0 };

        // Find length of longest bookTypes value.
        int maxLengthItem = 0;
        boolean firstValue = true;
        for (String bookType : bookTypes) {
            maxLengthItem = (firstValue) ? bookType.length() : Math.max(maxLengthItem, bookType.length());
            firstValue = false;
        }

        // Display rows of data
        for (int i = 0; i < bookTypes.length; i++) {
            // Use %6.2 instead of %.2 so that decimals line up, assuming max
            // book cost of $999.99. Change 6 to a different number if max cost
            // is different
            String format = "%d. %-" + Integer.toString(maxLengthItem) + "s \t\t $%9.2f\n";
            System.out.printf(format, i + 1, bookTypes[i], costs[i]);
        }
    }
}
Rick Upton
  • 31
  • 2
1

You can refer to this blog for printing formatted coloured text on console

https://javaforqa.wordpress.com/java-print-coloured-table-on-console/

public class ColourConsoleDemo {
/**
*
* @param args
*
* "\033[0m BLACK" will colour the whole line
*
* "\033[37m WHITE\033[0m" will colour only WHITE.
* For colour while Opening --> "\033[37m" and closing --> "\033[0m"
*
*
*/
public static void main(String[] args) {
// TODO code application logic here
System.out.println("\033[0m BLACK");
System.out.println("\033[31m RED");
System.out.println("\033[32m GREEN");
System.out.println("\033[33m YELLOW");
System.out.println("\033[34m BLUE");
System.out.println("\033[35m MAGENTA");
System.out.println("\033[36m CYAN");
System.out.println("\033[37m WHITE\033[0m");

//printing the results
String leftAlignFormat = "| %-20s | %-7d | %-7d | %-7d |%n";

System.out.format("|---------Test Cases with Steps Summary -------------|%n");
System.out.format("+----------------------+---------+---------+---------+%n");
System.out.format("| Test Cases           |Passed   |Failed   |Skipped  |%n");
System.out.format("+----------------------+---------+---------+---------+%n");

String formattedMessage = "TEST_01".trim();

leftAlignFormat = "| %-20s | %-7d | %-7d | %-7d |%n";
System.out.print("\033[31m"); // Open print red
System.out.printf(leftAlignFormat, formattedMessage, 2, 1, 0);
System.out.print("\033[0m"); // Close print red
System.out.format("+----------------------+---------+---------+---------+%n");
}
hemanto
  • 1,900
  • 17
  • 16