Recipe 10.3 Printing with the 1.5 Formatter


Problem

You have JDK 1.5 and you want the ease of use that the java.util.Formatter class brings to simple printing tasks.

Solution

Use Formatter for printing values with fine-grained control over the formatting.

Discussion

The 1.5 Formatter class is patterned after C's printf routines. In fact, PrintStream and PrintWriter have convenience routines named printf( ), which simply delegate to PrintStream 's format( ) method, which uses a default Formatter instance. However, since Java is an object-oriented language, the methods are strongly type-checked, and invalid arguments will throw an exception rather than generating gibberish.

The underlying Formatter class in java.util works on a String containing format codes . For each item that you want to format, you put a format code. The format code consists of a percent sign (%), an argument number followed by a dollar sign ($), an optional field width or precision, and a format type (d for decimal integer, that is, an integer with no decimal point, f for floating point, and so on). A simple use might look like the following:

System.out.format("%1$04d - the year of %2$f", 1951, Math.PI);

As shown in Figure 10-2, the "%1$04d" controls formatting of the year and the "%2$f" controls formatting of the value of PI.

Figure 10-2. Format codes examined
figs/jcb2_1002.gif


Many format codes are available; Table 10-1 lists some of the more common ones. For a complete description, refer to the Javadoc for java.util.Formatter.

Table 10-1. Formatter format codes

Code

Meaning

c

Character (argument must be char or integral type containing valid character value)

d

"decimal int" integer to be printed as a decimal (radix 10) with no decimal point (argument must be integral type).

f

Floating point value with decimal fraction (must be numeric); field width may be followed by decimal point and fractional digit field width; e.g., 7.2f.

e

Floating point value in scientific notation.

g

Floating point value, as per f or e, depending on magnitude.

s

General format; if value is null, prints "null", else if arg implements Formattable, format as per arg.formatTo( ); else format as per arg.toString( ).

t

Date codes; follow with secondary code. Common date codes are shown in Table 10-2. Argument must be long, Long, Calendar, or Date.

n

Newline; insert the platform-dependent line ending character.

%

Insert a literal % character.


Some examples of using a Formatter are shown in FormatterDemo.java, in Example 10-1.

Example 10-1. FormatterDemo.java
import java.util.Formatter; /** Demonstrate some usage patterns and format-code examples   * of the Formatter class (new in JDK 1.5).  */ public class FormatterDemo {     public static void main(String[] args) {         // The arguments to all these format methods consist of         // a format code String and 1 or more arguments.         // Each format code consists of the following:         // % - code lead-in         // N$ - which parameter number (1-based) after the code         // N - field width         // L - format letter (d: decimal(int); f: float; s: general; many more)         // For the full(!) story, see javadoc for java.util.Formatter.         Formatter fmtr = new Formatter( );         Object result = fmtr.format("%1$04d - the year of %2$f", 1951, Math.PI);         System.out.println(result);         // A shorter way of doing things. But this         // way you must provide the newline delimiter         System.out.format("%1$04d - the year of %2$f%n", 1951, Math.PI);         // So is this         System.out.printf("%1$04d - the year of %2$f%n", 1951, Math.PI);         // Format doubles with more control         System.out.printf("PI is about %1$4.2f", Math.PI);     } }

Running FormatterDemo produces this:

C:> javac -source 1.5 FormatterDates.java C:> java FormatterDates  1951 - The year of 3.141593 1951 - The year of 3.141593 1951 - The year of 3.141593 PI is about 3.14

For date and time formatting, a large variety of format codes are available.[2] Each must be preceded by a t, so to format the first argument as a year, you would use %1$tY. Table 10-2 lists some of the more common date and time codes.

[2] The 1.5 beta 1 documentation lists about 40 conversions plus another 6 "combination" codes; the exact list may change in the final release of 1.5.

Table 10-2. Formatting codes for dates and times

Format code

Meaning

Y

Year (at least four digits)

m

Month as 2-digit (leading zeros) number

B

Locale-specific month name (b for abbreviated)

d

Day of month (2 digits, leading zeros)

e

Day of month (1 or 2 digits)

A

Locale-specific day of week (a for abbreviated)

H or I

Hour in 24-hour (H) or 12-hour (I) format (2-digits, leading zeros)

M

Minute (2 digits)

S

Second (2 digits)

P or p

Locale-specific AM/PM in uppercase (P) or lowercase (p)

R or T

24-hour time combination: %tH:%tM (R) or %tH:%tM:%tS (T)

D

Date formatted as "%tm/%td/%ty"


In my opinion, using these in applications that you distribute or make available as web applications is a Really Bad Idea because any direct use of them assumes that you know the correct order to print these fields in all locales around the world. Trust me, you don't. Instead of these, I recommend the use of DateFormat, which I show you how to use in Recipe 6.2; I also urge you to read Chapter 15. However, for "quick and dirty" work, as well as for writing log or data files that must be in a given format because some other program reads them, these are hard to beat.

Some date examples are shown in Example 10-2.

Example 10-2. FormatterDates.java
import java.util.Formatter; import java.util.Date; import java.util.Calendar; /** Demonstrate some usage patterns and format-code examples   * of the Formatter class (new in JDK 1.5).  */ public class FormatterDates {     public static void main(String[] args) {         // Format numbers as dates e.g., 2004-06-28         System.out.printf("%1$4d-%2$02d-%3$2d%n", 2004, 6, 28);         // Format fields from a Date object: multiple fields from "1$"         // (hard-coded formatting for Date not advisable; see I18N chapter)         Date today = Calendar.getInstance( ).getTime( );         System.out.printf("Today is %1$tB %1$td, %1$tY%n", today);  // e.g., July 4, 2004     } }

Running this FormatterDates class produces the following output:

C:> javac -source 1.5 FormatterDates.java C:> java FormatterDates 2004-06-28 Today is March 07, 2004

The astute reader will notice that this mechanism requires that the Java language now contain a variable arguments mechanism. Var args have been the bane of developers on many platforms and, indeed, they have finally come to Java. However, they are not intended for capricious use, and I do not document them here.[3] If you really need to use this mechanism, consult the documentation accompanying JDK 1.5.

[3] Well, if you insist. But only briefly. The variable argument, which must be the last declaration in the method's header, is declared as Type . . . name, and is treated as Type[] in the body of the method. Don't forget to compile with -source 1.5. The invocation must pass a comma-separated list of arguments of the same or compatible types. See lang/VarArgsDemo.java in the online source.



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net