Java Reference
In-Depth Information
Having set the orientation for the
PageFormat
object, the methods returning the coordinates for the
position of the printable area and the width and height all return values consistent with the orientation.
Thus the width of the printable area will be greater than the height if the orientation has been set to
LANDSCAPE
. Everything looks fine until we try it out. If you recompile with this modification to
SketchView
, the sketch is printed landscape, but the output is clipped so that a portion of the sketch to
the right of the page in landscape orientation is missing. Indeed it looks very much as though the width
of the printable area in landscape orientation is the same as that for portrait orientation.
That's exactly true, and this is a clue to what's wrong. We have modified the
PageFormat
object to
landscape orientation, but the
Graphics2D
object that was passed to our
print()
method was
produced based on the
PageFormat
object in its original state - portrait orientation. If we had known
ahead of time back in the
actionPerformed()
method in the
FileAction
inner class to
SketchFrame
, we could have set up the
PageFormat
object for the print job before our
print()
method ever gets called. This could be done by modifying the code that initiates printing in the
actionPerformed()
method like this:
// Get a printing object
PrinterJob printJob = PrinterJob.getPrinterJob();
PrintService printer = printJob.getPrintService();
if(printer == null) {
JOptionPane.showMessageDialog(SketchFrame.this,
"No default printer available.",
"Printer Error",
JOptionPane.ERROR
_
MESSAGE);
return;
}
PageFormat pageFormat = printJob.defaultPage();
SketchView theView = theApp.getView();
Rectangle rect = theView.getModelExtent(); // Get sketch bounds
// If the sketch width is greater than the height, print landscape
if(rect.width>rect.height)
pageFormat.setOrientation(pageFormat.LANDSCAPE);
printJob.setPrintable(theView, pageFormat);
Calling the
defaultPage()
method for a
PrinterJob
object returns a reference to the default page
for the current printer. You can then change that to suit the conditions that you want to apply in the
printing operation and pass the reference to an overloaded version of the
setPrintable()
method.
The call to
setPrintable()
here makes the
printJob
object print using the
theView
object as the
Printable
, object
,
using the
PageFormat
object specified by the second argument. With this code
we would not need to worry about the orientation in the
print()
method for the
Printable
object.
It is taken care of before
print()
ever gets called.
However, while the code above provides a good solution it is interesting to look into how we can
change the clip rectangle; let's see how we can make our
print()
method accommodate landscape
orientation. To make the printing work properly we need to reset the clip rectangle in the
Graphics2D
object to reflect the landscape orientation of the paper. It actually isn't that difficult. We can amend
print()
like this: