Last Updated: December 6, 1999
Purpose
The goal for the AWT printing API is to give developers an easy mechanism to
print the AWT components using native platform facilities. This API is designed
for use with the AWT Graphics model. Developers who prefer to work with
Graphics2D should use 2D printing, available in the java.awt.print
package.
The Printing API
The printing API is very simple and consists primarily of one method in class
java.awt.Toolkit:
PrintJob getPrintJob(Frame f, String jobtitle, JobAttributes jobAttributes, PageAttributes pageAttributes)
and a class responsible for encapsulating all the information associated with a printing request:
java.awt.PrintJob
The getPrintJob() method in Toolkit will take care of posting any platform specific print dialogs so that when it returns, the PrintJob object has already been configured to match the user's request. The JobAttributes and PageAttributes parameters provide the ability to pass in default attribute values for the print job. This allows the printing attributes appropriate for a particular application to be stored and applied in individual circumstances. If the user changes the default attributes in the print dialog, those changes are saved into the JobAttributes and PageAttributes instances passed to the method (so the program can choose to store those new defaults if desired).
The PrintJob object provides access to the relevant printing properties
chosen by the user (page size, etc) as well as the print graphics contexts used
to transparently render to the print device.
Print Graphics Context
The print graphics context is provided by an interface:
java.awt.PrintGraphics
The PrintJob object provides the method to obtain a handle to an object which is a subclass of Graphics AND implements the PrintGraphics interface:
Graphics getGraphics()
Since this object is a subclass of the Graphics class, it can simply be passed into existing paint() or print() methods (which use the standard Graphics drawing methods) and the underlying AWT implementation takes care of translating those calls to the appropriate print device (this is straightforward on Mac/Windows which support graphic print devices; on Solaris, a PostScript graphics object is required to generate appropriate PostScript).
It is often the case that from within a paint() or print() method, your program may want to detect whether it is rendering to the screen or to a print device (for example it would not necessarily want to print `highlighted' text which has been selected by the user). Since the graphics object returned from the PrintJob.getGraphics() method implements the PrintGraphics interface, this can easily be detected with the following test:
public void paint(Graphics g) {
if (g instanceof PrintGraphics)
// printing is occurring
...
The primary method in the PrintGraphics interface is a method to obtain a handle to the associated PrintJob object:
PrintJob getPrintJob()
These printing attributes can be obtained by the following methods on java.awt.PrintJob:
Dimension getPageDimension()
int getPageResolution()
public void printAll(Graphics g)
Calling this method will result in the complete traversal of the containment hierarchy such that the print() method will be called on all descendent components. The default implementation of the print() method simply calls paint(), so if a program has created a component which renders itself in the paint() method, printing should work "automagically". Note that all the base AWT components (Button, Scrollbar, etc.) are capable of printing themselves when their printAll() method is called (even though their rendering does not take place in the paint() method).
It's important to note that this restriction does not limit applets' capability
to render using a PrintGraphics object returned from a PrintJob; it just
disallows untrusted applets to initiate the job. A more reasonable policy will
be provided when the Java security architecture allows more customization.
Sample Code
A VERY simple example of how a print job can be initiated to print an AWT
component:
import java.awt.*;
import java.awt.event.*;
public class PrintingTest extends Frame implements ActionListener {
PrintCanvas canvas;
public PrintingTest() {
super("Printing Test");
canvas = new PrintCanvas();
add("Center", canvas);
Button b = new Button("Print");
b.setActionCommand("print");
b.addActionListener(this);
add("South", b);
pack();
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.equals("print")) {
PrintJob pjob = getToolkit().getPrintJob(this,
"Printing Test", null, null);
if (pjob != null) {
Graphics pg = pjob.getGraphics();
if (pg != null) {
canvas.printAll(pg);
pg.dispose(); // flush page
}
pjob.end();
}
}
}
public static void main(String args[]) {
PrintingTest test = new PrintingTest();
test.show();
}
}
class PrintCanvas extends Canvas {
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
public void paint(Graphics g) {
Rectangle r = getBounds();
g.setColor(Color.yellow);
g.fillRect(0, 0, r.width, r.height);
g.setColor(Color.blue);
g.drawLine(0, 0, r.width, r.height);
g.setColor(Color.red);
g.drawLine(0, r.height, r.width, 0);
}
}