Earlier in this chapter, we hinted at the possibility that
you could draw the same stuff on the screen and the printer. It’s true;
all you really need to do is get a Graphics2D
object that represents a printer
rather than an area of the screen. Java’s printing API provides the
necessary plumbing. There isn’t room here to describe the whole Printing
API, but we will provide you with a short example that will let you get
your feet wet (and your paper flowing).
The printing classes are tucked away in the java.awt.print
package.
You can print anything that implements the Printable
interface. This
interface has only one method—you
guessed it, print()
—which is like the
paint()
methods we’ve already worked
with. It accepts a Graphics
object that
represents the drawing surface of the printer’s page. It also accepts a
PageFormat
object that encapsulates
information about the paper on which you’re printing. Finally, print()
is passed the
number of the page that is being rendered. All Swing components implement
a print()
method, which you can use or
override to customize their printed appearance.
Your print()
implementation
should either render the requested page or state that it doesn’t exist.
You can do this by returning special values from print()
, either Printable.PAGE_EXISTS
or Printable.NO_SUCH_PAGE
.
You can control a print job, including showing print and page setup
dialogs, using the PrinterJob
class.
The following class enables you to get something on paper. In this
example, we work both sides of the printing equation: implementing a
simple Printable
interface to generate
our data and printing it with the PrinterJob
API.
//file: UnbelievablySimplePrint.java
import
java.awt.*
;
import
java.awt.print.*
;
public
class
UnbelievablySimplePrint
implements
Printable
{
private
static
Font
sFont
=
new
Font
(
"Serif"
,
Font
.
PLAIN
,
64
);
public
int
(
Graphics
g
,
PageFormat
Pf
,
int
pageIndex
)
throws
PrinterException
{
if
(
pageIndex
>
0
)
return
NO_SUCH_PAGE
;
Graphics2D
g2
=
(
Graphics2D
)
g
;
g2
.
setFont
(
sFont
);
g2
.
setPaint
(
Color
.
black
);
g2
.
drawString
(
"Save a tree!"
,
96
,
144
);
return
PAGE_EXISTS
;
}
public
static
void
main
(
String
[]
args
)
{
PrinterJob
job
=
PrinterJob
.
getPrinterJob
();
job
.
setPrintable
(
new
UnbelievablySimplePrint
());
if
(
job
.
printDialog
())
{
try
{
job
.
();
}
catch
(
PrinterException
e
)
{}
}
System
.
exit
(
0
);
}
}
There’s not much to this example. We’ve created an implementation of
Printable
, called UnbelievablySimplePrint
. It has a very simple
print()
method that draws some
text.
The rest of the work, in the main()
method, has to do with setting up the
print job. First, we create a new PrinterJob
and tell it what we want to
print:
PrinterJob
job
=
PrinterJob
.
getPrinterJob
();
job
.
setPrintable
(
new
UnbelievablySimplePrint
());
Then, we use the printDialog()
method to
show the standard print dialog. If the user presses the OK button,
printDialog()
returns true
and main()
goes ahead with the printing.
Notice that in the print()
method, we perform the familiar cast from Graphics
to Graphics2D
. The full power of the 2D API is
available for printing. In a real application, you’d probably have some
subclass of Component
that was also a
Printable
. The print()
method could simply call the component’s
paint()
method to create a component
that performs the same rendering to both the screen and the
printer.
Get Learning Java, 4th Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.