Speaker (SPK-rblancha): Richard Blanchard of RBI systems
Moderator (MDR-edort): Edward Ort
This is a moderated forum.
MDR-edort: Welcome to JavaTM Live. Today's topic is
printing APIs for the Java 2 platform. Our guest is Richard
Blanchard of RBI systems. Richard designed and implemented the APIs. Start
sending your questions to Richard. And thanks for joining!
joey.eccleston: I've been told the 2D API is what I
need to do report printing from Java. We have the GUI portion in place as far
as displaying data. Now we want to print this data out in a more formalized
report format. Is the 2D API what I want to be looking at?
SPK-rblancha: The new printing APIs were designed to support
Java 2D (though they are independent) and so if you are using Graphics 2D to
render your pages you'll want to use the new printing APIs. If you are using
AWT and the Graphics class you can use the older AWT printing
code.
The performance of the new printing API is not what it should be and you should
be wary. That is being fixed for a subsequent JDKTM release. Also, the new
printing APIs, which I really like, can be a bit confusing for those used to
the AWT printing API. I'm working on a tutorial for the new printing APIs for
Sun and you can get a draft at
www.rbi.com/~rblancha.
The tutorial gives a good summary of the design decisions behind the new API.
Its most unique feature is that it turns the printing loop inside-out. Rather
than having the application have a printing loop through the pages of a
document, the application generates a description of the pages of the document
and then the printing subsystem runs the printing loop. This is similar to the
way in which the AWT runs the display loop and calls paint on the
components that need to be drawn.
JoeSam: I wonder if Richard could discuss,
for the benefit of the participants and archive readers:
- What developers can do to minimize the size of spooled files
and to speed up, particularly, text/report print.
- Future plans and potential time availability (without putting
your back against the wall) of improvements in this area.
I know your group is aware of a number of concerns and this would be a great
place to clarify the issues. Thanks.
SPK-rblancha: First the excuse: the printing API came along
very late in the Java 2 (formerly JDK 1.2) development cycle. Much of
the development time went into the API design and development of the raster
path. The raster path can print all of the Java 2D primitives on both the
SunTM and SolarisTM reference releases. This was the goal of the
initial JDK implementation. At the very end we snuck in an optimized case that
converted some primitives to outlines.
In order to avoid the raster path of the printing API, a developer can draw
shapes and text with no alpha component and using only the solid paint type. If
all of the drawing on a page meets these criteria, then the raster path is
avoided and the outline printing code is invoked. That's about the best a
developer can do today.
We're currently working on "real" text and images to further extend
the non-raster case.
joey.eccleston: Our data is presented in the GUI as
several tabbed JPanels containing JTables which
scroll when necessary. Is something magical going to happen when using this API
that prints out more on the hard copy than is visible to the user of the GUI?
SPK-rblancha: There is no magic here. If you look at the new
APIs you'll see a Book class. If you implement the
Printable interface for each of your panes and then add each
printable as a page in a Book instance you'll then ask the print
system to print the Book instance.
One of the features that is just outside the printing APIs and that I will be
adding to the tutorial is a Vista class that can spread a
component larger than a single page over multiple pages. That might be useful
for the case where your JTables are longer than a page.
JoeSam: The info regarding raster path avoidance is
just the sort of thing we need. Could you post some code (or point us to a
reference) that makes it very clear how to accomplish that?
SPK-rblancha: I'll promise to add that to the tutorial by next
week. (See www.rbi.com/~rblancha).
So just look for an update there.
Once the tutorial gets out of draft stage it should make it up to the
developer's area.
MDR-edort: Will the tutorial include code samples?
Can you highlight some of the things that users of the AWT printing APIs need
to watch out for when they use the new printing APIs?
JoeSam: Could you expand on the moderator's initial
question re: differences to watch out for or consider in Java 2D printing vs.
AWT?
SPK-rblancha: It currently has several sample programs that
use the API. I next intend to add a sample showing the printing of a
JTable. The interaction between Java Foundation Classes (JFC)
Project Swing (Project Swing) and printing can be a bit unexpected when Project
Swing's double-buffering is enabled. Basically what gets printed, unless the
developer is careful, is the component's backing store and printing comes out
as 72dpi raster.
In the AWT printing path (and in most printing loops) the application marks the
beginning of the first page, draws the page, marks the end of the page, and
then moves on to each subsequent page.
The model posed several problems for Java 2D. Because Java 2D is more powerful
than the existing printer description languages, the printing system needed a
spool file format in order to convert Java 2D calls to the printer's control
language. This spool file did not exist and still does not.
The solution was to have the printing APIs call back to the application when it
needed a page or part of a page drawn. One example is in the raster case, where
the printing system needs to create raster bands of a page for the printer. The
printing API calls back to the application once for each band on the page that
contains drawing. The net result is that the application has a
print method that is invoked similarly to a component's
paint method. The application does not know how many times
print will be invoked per page nor in what order the pages may be
imaged.
Just to give you the whole picture, for the current implementation, the
print method for page is invoked once to gather page metrics. In
this call, the clip is the entire page and signals that the application should
render the whole page. The print system looks at the types of drawing being
done and the coverage of the page. Based on this information it decides whether
to render that page as raster bands or as shape outlines. If the raster path is
chosen then the coverage information is used to avoid imaging blank portions of
the page.
JoeSam: Yes, I've seen questions on the lists
regarding 72 dpi output on high resolution printers. Probably another good area
for clarification in your tutorial. Any thread issues to watch out for due to
the Project Swing interaction? Differences if one is using AWT components?
SPK-rblancha: The obvious future direction is to improve
performance, and we are actively working on that. Today text is rendered as a
shape outline with the expected speed and quality impact. The current step will
map text calls to the underlying GDI or PostScript code and will result in a
good speed and quality jump. Images currently force the entire page into the
raster path and should not in general do so. We'll be mapping images directly
to GDI and PostScript image calls. This takes care of many cases that force
raster. Per JoeSam's question: the printing API is very threadable. One could
have several threads all printing different jobs at once. The application needs
to protect its data but the printing system is ready to go there.
MDR-edort: Not sure I understand all the implications of
"the application needs to protect its data." Are there special data
protection implications relevant to the use of the printing APIs?
SPK-rblancha: The threading question does raise one of the
more onerous parts of the new API. The application is required to
"freeze" its concept of page during printing. Because the printing
API may call the application many times to render different parts of a single
page, the application cannot change its concept of a page during the print
loop. If an application threads printing and leaves it UI live, then it must
clone its page representation. The application's data protection for threading
includes this cloning as well as the usual syncronizing of shared data between
the threads to maintain data consistency.
joey.eccleston: Is the 2D API usable as a separate
library from Java 2?
SPK-rblancha: No it is not. The Java 2D code is only
available as part of Java 2. Sorry.
JoeSam: My background is in the IBM midrange, so I
actually know what 'spool' stands for. Re: your comment that 'the spool file
did not and does not exist'do you mean a proprietary format or no class
for it, or what?
SPK-rblancha: The lack of a spool file format that I mention
was shorthand (sorry) for the inability to write to disk a representation of
the Java 2D and AWT drawing commands invoked by an application. Had this
existed, a traditional print system would write the application's drawing
command to a disk file and then render the drawing commands from that file as
needed to image bands of a page or to gather metrics. The lack of that disk
format caused the creation of the print system calling the application back to
simulate this functionality. As a benefit the API became more powerful and is
better at supporting higher level print features like reverse order printing
and booklet printing than are traditional print systems.
joey.eccleston: I've been told color printing isn't
supported very well. Any comment?
SPK-rblancha: I do not know of any deficiencies in the color
support. In the raster code path the application's drawing is rendered into 32
bit-per-pixel raster buffers and then sent to the underlying GDI or PostScript
device. I'd be interested in hearing what color problems people were having.
JoeSam: Richard, thanks very much for an informative
session. I hope you'll be back to report on improvements.
SPK-rblancha: Thank you for the questions. I expect you'll see
good strides in the near future for Java printing.
MDR-edort: Thanks from me too. And thanks to all of our
participants. The session is over. Thanks again for joining.
Reader Feedback
Tell us what you think of this transcript.