String support
The String
class has two new static format()
methods that work similarly to their printf()
equivalents. Send a format string and arguments (with a possible
Locale
) and use what is
specified in the format string to convert the arguments. In the case of the String
version of the method, the results are sent back as a
String
object, instead of going through the stream.
These methods aren't overly spectacular, but they
allow you to avoid using the Formatter
object
directly and creating an intermediate StringBuilder
.
Formatting arbitrary objects
Everything you've seen so far describes how to use the new formatting capabilities to format existing
objects and primitive types. If you want to provide support for using your own objects
with Formatter
, that's where the
Formattable
interface comes into play. By implementing
the single formatTo()
method shown in Listing 6 in your
own class, you can use your own classes with format strings:
Listing 6. Formattable interface
void formatTo(Formatter formatter,
int flags,
Integer width,
Integer precision)
|
Listing 7 demonstrates the use of the Formattable
interface by
providing a simple class with a name property. That name is displayed in the output,
with support for controlling the width of the output and the justification.
Listing 7. Example formattable usage
import java.util.Locale;
import java.util.Formatter;
import java.util.Formattable;
public class MyObject implements Formattable {
String name;
public MyObject(String name) {
this.name = name;
}
public void formatTo(
Formatter fmt,
int f,
Integer width,
Integer precision) {
StringBuilder sb = new StringBuilder();
if (precision == null) {
// no max width
sb.append(name);
} else if (name.length() < precision) {
sb.append(name);
} else {
sb.append(name.substring(0, precision - 1)).append('*');
}
// apply width and justification
if ((width != null) && (sb.length() < width)) {
for (int i = 0, n=sb.length(); i < width - n; i++) {
if ((f & Formattable.LEFT_JUSTIFY) == Formattable.LEFT_JUSTIFY) {
sb.append(' ');
} else {
sb.insert(0, ' ');
}
}
}
fmt.format(sb.toString());
}
public static void main(String args[]) {
MyObject my1 = new MyObject("John");
MyObject my2 = new MyObject("Really Long Name");
// First / Using toString()
System.out.println("First Object : " + my1);
// Second / Using Formatter
System.out.format("First Object : '%s'\n", my1);
// Second / Using Formatter
System.out.format("Second Object: '%s'\n", my2);
// Second / Using Formatter with width
System.out.format("Second Object: '%10.5s'\n", my2);
// Second / Using Formatter with width and left justification
System.out.format("Second Object: '%-10.5s'\n", my2);
}
}
|
Running this program produces the output in Listing 8. The first two
lines demonstrate the difference between using toString
and Formatter
. The last three show options for
width and justification control.
Listing 9. Example formattable output
First Object : MyObject@10b62c9
First Object : 'John'
Second Object: 'Really Long Name'
Second Object: ' Real*'
Second Object: 'Real* '
|