|
J2TextPrinter known problems |
|
The Java 2 printing model was new in JDK 1.2 and there were a large
number of problems there were not fixed until the JDK 1.3
release. More problems were fixed in JDK 1.4, which also added
some important new features. For these reason, the use of JDK
1.4 or later, and preferably the current JDK, is strongly
recommended. This section documents problems present in
Java that can impact your use of J2PrinterWorks.
Known Java problems affecting J2TextPrinter
Uneven
character spacing when printing JTextPane, JEditorPane, or JTextArea -
Bug Parade 6488219
Fixed in JDK 1.6.0_10.
Printing text using JTextPane,
JEditorPane, or JTextArea can result in uneven spacing between
characters depending on the font, as though the wrong kerning
information is being used. Some letters have too much space after them,
resulting in noticable (several pixel) gaps with the following letters.
Other letters have too little space after them, resulting in their
touching the letters that follow them.
The problem only occurs in printed output, the screen display looks
fine.
The problem occurs for JTextComponent subclasses but not when printing
the same strings using drawString.
This was not a problem under JDK 1.4 but appeared starting with JDK 1.5
and continues in JDK 1.6. In JDK 1.5 some much more serious character
spacing problems were fixed (see Bug Parade 4724061 and 4352983), which
apparently introduced this new problem.
Incomplete
printing of HTML document containing PNG image to certain networked
printers
Fixed in JDK 1.5.
We have had customer reports that an
HTML document containing a PNG image will cause the document to
terminate at the point of the PNG image when printing
across the network to a Windows shared printer. The problem
occured for a Windows XP client printing to certain HP inkjet printers
(HP InkJet 22/30 and HP OfficeJet G55) on a Windows NT server. The same HTML document prints correctly
across the network to the same printer and NT system under Internet
Explorer. The same document
prints correctly to other HP printers (e.g. HP LaserJet 6L, HP PSC
2410), to non-HP printers on the NT server, and when the server was
Windows 2000 or XP. The problem occurs for JDK 1.3.1 and
JDK 1.4.2, but is fixed in JDK 1.5. A workaround for earlier
JDK's is to use a GIF or JPG image instead of PNG.
Text and borders
in HTML table run over right edge -
Bug Parade 4764897
Fixed in JDK 1.5.
Significant drawing errors can occur
for the rightmost column of HTML tables in JTextPane. For
certain text and widths, text in the right column will fail to wrap
properly within the HTML table cell and can
overshoot the right table border by several characters. Iappears to
be triggered when an earlier
cell of the HTML table has a non-breaking word of size
greater than its cell width.
HTML
table only supports border=0 or border=2 - Bug
Parade 4174871
Fixed in JDK 1.5.
Java displays and prints
HTML tables either with no border (same as border=0, which is
the default), or with border=2 if you specify border=n
for any n>0. A workaround to get 1 pixel wide lines
is to convert the HTML table to a JTable, break the JTextPane into two
parts, and use a J2FlowPrinter with a J2TextPrinter followed by a
J2TablePrinter followed by another J2TextPritner.
HTML table
border displays but won't print -
Bug Parade 4691546
Fixed in JDK 1.5.
When using a JTextPane to display HTML, if the HTML uses the <table
border> tag, it displays the table with a border, but if you
serialize the StyledDocument of the JTextPane (such as printing with
setCloningUsed(true), the default),
the border disappears. Other HTML tags and subtags serialize OK
and the table itself comes out OK, just the border is lost. A
workaround is to setCloningUsed(false), but there is no workaround if
you need cloning turned on and are also using table borders.
The
<center> tag doesn't work if using
HTMLEditorKit -
Bug Parade 4671625
When using HTMLEditorKit to read HTML into a JTextPane, the <center> tag does not
work, the text stays left justified. The <center> tag
is widely used by HTML editors (e.g. Netscape), so it's a pain not
to have this work. Workarounds: the tags <div
align=center> and <p align=center> work OK. The
<center> tag works OK you have the JTextPane read the same HTML
from a file using:
URL url = new
File(fileName).toURL();
myJTextPane.setPage(url);
HTML body
doesn't display if <META
content="text/html"> in <head>
section -
Bug Parade 4695909
Fixed in JDK 1.5.
When the tag <meta http-equiv=Content-Type content=text/html> is
included in the HEAD section of an
HTML document read in using setText(String), JTextPane fails to
render the body section entirely.
Workaround: parse the HTML
String and remove everything in the
HEAD section before calling setText(String).
The problem is a result of a font metrics mismatch between the screen and the printer due to their differing resolutions. Depending on the characters involved, a given number of display pixels don't convert to an exact number of printer pixels, and the cummulative round-off error can build up to a large number of pixels, either too many or too few. When the style changes, Java sets the absolute printer position for the next run of text based on this calculation, and all the cumulative error shows up at once, resulting in either a gap or overlapping characters.
A workaround is to cause this repositioning to occur after every
word or even after every character so that the error never gets too
large. If the JTextPane is defined using HTML, then every new
HTML tag causes this repositioning to take place. A sequence such
as <b></b> does nothing and so it can be inserted as often
as desired to bring about this effect. The smallest sequence that
appears to work and have no effect on the display is <a>.
This is the hyperlink ("anchor") tag with no HREF or other subtags, so
a closing </a> is not required. If you employ this
technique after every character, you may discover that for certain
fonts it is counter-productive after some characters (for example: l,
m, n, i, ...), which would do better left alone. A further
refinement in this case is to build a "kerning" table indicating which
characters are OK to follow with <a> and which are not. The
general idea is to place the repositionings where they are least
noticeable, e.g., after whole words and after those characters whose
width favors it.
Text clipped at right edge of JTextPane
(or JLabel) -
Bug Parade 4352983
Fixed in JDK 1.5.
Some JTextPanes with long lines will print with the rightmost
character(s) partially clipped off. The problem does not occur on
the screen. The problem can also occur in JLabel instances,
including in the J2PrinterWorks headers and/or footers. A
workaround for the JLabel case is to pad your JLabel String with one or
two extra
spaces. The <a> tag technique described under "Text styles
shifted left or right" also works.
Problems importing RTF documents
J2TextPrinter is built on Java's JTextPane print (and
related) methods. The native Java StyledDocument format
(DefaultStyledDocument) is well supported for both display and printing
by JTextPane and thus J2TextPrinter. Unfortunately, JTextPane has
some problems supporting the RTF format, and these in turn affect
J2TextPrinter.
JTextPane only imports a limited subset of the RTF format (see Bug Parade 4261277 and Bug Parade 4723383). It will preserve most styles and sizes correctly but substitutes SansSerif font for anything that isn't exactly the same name as the fonts used by Java (on Windows these are: Time New Roman, Arial, Courier, Symbol, and WingDings). Many other key RTF features, including embedded graphics and tables, are also not supported. However, whatever JTextPane imports and displays in the application window, J2TextPrinter is able to print reliably.
There are many postings on Sun's Bug Parade requesting that Sun
address the problem of missing or broken RTF features.
Unfortunately, Sun's responses are generally negative and include
statements like these:
"The demand for RTF support seems to be low, so
implementing this is a very low priority."
"Unfortunately the rtf support in Swing is rather
limited, and we don't plan on fixing this at this time."
There was even talk that Sun would drop RTF support altogether, though
this hasn't happened. Based on this, Java's support for RTF is very
unlikely to improve over its current state, and we therefore strongly
advise you to either switch to the StyledDocument or HTML
formats or restrict your use of RTF to just that narrow subset of
features
that presently work.
There is also a commercially-available RTF converter from Novosoft which is callable from Java and can convert RTF (including embedded graphics and tables) to the XML XSL FO format. This package references converters which can transform XSL FO to HTML, PDF, Postscript, and other formats.
Problems importing HTML documents
Fixed in JDK 1.4
Java has continued to improve its HTML support from JDK 1.2 to 1.3 to
1.4. While it can display basic HTML 3.2 web
pages including images, tables, and frames, the capabilities fall short
if you try to print any given web page or a page composed with HTML
editing tools such as Netscape or FrontPage. As with RTF, your
document
must explicitly use the Java fonts by name, otherwise it will
substitute
SansSerif. As a result, the "Variable Width" font setting common
in HTML documents winds up as SansSerif instead of Serif as in the
standard
browsers. Also, prior to JDK 1.4, Java substituted larger font
sizes
for the "logical" HTML font sizes compared to the standard browsers
(see
Bug
Parade 4285636 , a workaround is to use "relative" font sizes,
see
discussion for J2Label
). Other spacing, alignment, and bullet style properties are
approximated at best. HTML tables can only have either no border
or border=2. HTML tables will only paginate
on major row boundaries. In general, for any given HTML tag,
only a subset of subtags are supported.
Images in HTML documents in wrong folder
The standard web browers assume that the images referenced with IMG
tags in an HTML document are in the same folder (directory) as the
.HTML file itself. But in Java, loading your HTML document using
the statements:
java.net.URL url = new
java.net.URL("file",null,fileName);
yourJTextPane.setPage(url);
loads the HTML images from the program folder (i.e., the folder
you were in when your program is executed), not the document folder
(i.e., where the HTML document itself is), see
Bug Parade 4294902 (and related bugs
4456393 ,
4252701 , and
4472003 ). A workaround for this problem is to
access your HTML document with the statements:
java.net.URL url = new File(fileName).toURL();
yourJTextPane.setPage(url);
which will cause the images to be located properly relative to the
document folder. This workaround is incorporated in
the J2TextPrinterTestApplication sample code.
Document serialization doesn't work
across Java versions
Solution provided in JDK 1.4
Sun serialization of documents is not compatible
across JDK releases. This means, for example, that the documents
J2TextPrinterTestApplication or Stylepad save under one JDK version
(e.g. 1.2.2) can only be read back by that release and
not by any other JDK version (e.g., 1.3, 1.3.1, 1.4, 1.4.1, 1.4.2,
etc.), and
vice-versa. In addition, the class HTMLDocument itself is not
serializable, see
Bug Parade 4630761. However, JDK 1.4 added new XML classes
XMLEncoder and XMLDecoder that provide an effective way to achieve
long-term persistence of Java objects across different JDKs starting
with 1.4. To keep J2TextPrinterTestApplication and Stylepad
usable under all JDKs, they have not been modified to take advantage of
these
new XML persistence classes.
Can't insertIcon(Image) in an HTML
document
Fixed in JDK 1.6
Due to a bug in the Java JTextPane implementation (see
Bug Parade 4671653 and Bug
Parade 4636235), you cannot embed an instance of the Java class
Image into an HTML document in a JTextPane using the method JTextPane.insertIcon(Image)
. However, the HTML
document itself can contain images using the usual <IMG
SRC=image.gif> tag. Also, the J2FlowPrinter component of
J2PrinterWorks
also lets you print HTML in a J2TextPrinter instance, followed
immediately by a J2PanelPrinter instance containing an Image, followed
immediately by more HTML in a second J2TextPrinter instance..
However, Java serialization is not perfect and this cloning operation can sometimes fail depending upon the complexity of your JTextPane, particularly if you have embedded components (also note that HTML document serialization itself is broken in JDK 1.4, see Bug Parade 4630761.). If your JTextPane cannot be cloned, J2TextPrinter will throw a com.wildcrest.j2printerworks.CloneException, and you will need to call setCloningUsed(false) in order to print. However, in this case your original JTextPane and not a cloned copy will be added to a different view as part of printing and removed from your view hierarchy, causing it to disappear. To avoid this problem, you should use one of the following approaches:
1) Print using a JTextPane that is not and never was displayed.
2) Print using a second, equivalent, completely independent JTextPane
which uses separately constructed copies of all embedded components and
which matches exactly the contents of your on-screen JTextPane
but is not itself displayed on the screen. Typically this second
JTextPane will be built in parallel with your displayed JTextPane using
duplicate operations.
3) Temporarily remove your JTextPane from your on-screen Frame (or
JFrame, etc.) while printing using:
frame.getContentPane().remove(yourJTextPane);
J2TextPrinterTestApplication switches to this approach if it gets a
CloneException when trying to clone your JTextPane. After
printing is done, you can add your JTextPane back to your view
hierarchy, or you may find it easier to rebuild your entire Frame.
4) Avoid embedded components entirely and instead use
a J2FlowPrinter to alternate J2TextPrinter instances with
J2PanelPrinter instances containing the desired components.
However, note
that this approach does not allow you to embed components within lines
of
text, rather each component will appear on its own line alternating
with
your text down the page.
In addition, if
you have an embedded component in your JTextPane and you call
setCloningUsed(false), then J2PrinterWorks must call setVisible(true)
on the
internal imaging JFrame it uses as part of printing (or print
preview). This causes a "printing..." tab to show up in the
Windows
task bar, which is not removed when printing completes. Calling
the J2TextPrinter dispose() method after printing completes will
deallocate this JFrame and
thereby cause the "printing..." tab to go away.
Note that due to a regression error, Java can't print embedded
components under JDK 1.4 at all, see
Bug Parade 4708924, but this was fixed in JDK
1.4.1.
A related problem is that if you have embedded components in
your JTextPane and print using the "Print" button in the print preview
dialog, the components can fail to print in the JTextPane (gaps will
appear where the components would have gone). The problem does
not occur when you invoke print directly, i.e., not from print
preview. In addition to trying the above techniques, a reliable
workaround for this problem is to use setSeparatePrintThread(false)
.
A refinement is to call setSeparatePrintThread(false)
just before calling showPrintPreviewDialog()
, then
restore setSeparatePrintThread(true)
when the print
preview dialog returns, so that printing from the print preview dialog
will use the same thread but regular printing will still use a
background thread.
Null Pointer Exception if print or print
preview while editing
embedded JTable cell
Components embedded in a JTextPane such as JTable, JTree, JTextField,
etc. are "live", in that you can edit them and print
the results. However, Java throws a Null Pointer Exception if
you print or print preview while in the middle of editing a JTable
cell. The problem does not occur if you hit <CR> or tab out
of the open cell in order to finalize your entry. A workaround is
to include an explicit call to JTable.getCellEditor().stopCellEditing()
in order to perform the equivalent of tabbing out of the cell
just before calling print() or showPrintPreviewDialog().
Text insertion caret in embedded text
components
J2TextPrinter controls the focus of the JTextPane being printed so that
the text insertion caret does not appear in printed output.
However, if you have embedded text components in your JTextPane,
J2TextPrinter cannot control whether one of these components will have
focus and print with a text insertion caret. Workarounds include
having your embedded components not be focus traversable,
calling setEditable(false) on your JTextPane, moving the
focus to some other window when printing, or not having a text
component
as the first embedded component in your document. Printing from
the same thread also appears to fix the problem since it does not
permit the UI thread to update the focus during printing.
CloneException
when printing
documents containing special (e.g. Unicode) characters
Fixed in JDK 1.4.2.
Due to a bug in Java, printing documents containing non-ASCII (e.g
Unicode) characters cause Java to throw a NotSerializableException,
which J2PrinterWorks rethrows as a CloneException. This problem
can be avoided by calling setCloningUsed(false), but there is no
workaround if cloning is required. This problem was fixed in JDK
1.4.2.
Printing JTextPane with embedded
components throws IllegalStateException
(JDK
1.4.0, JDK 1.4.2) -
Bug Parade 4708924
Regression from JDK 1.3.1, fixed in JDK 1.4.1, broken in
1.4.2, fixed in 1.4.2_02
When Java tries to print (or print preview) embedded components under
JDK
1.4, it throws the exception:
java.lang.IllegalStateException: constrain(xywh)
not
supported for complex transform
This problem was fixed in JDK 1.4.1, broken again in
1.4.2, and fixed again in 1.4.2_02. The problem was a regression
from
JDK 1.3.1 where printing embedded components worked OK. Embedded
components
in JTextPane has always been a somewhat flaky feature of Java, and we
recommend
you instead use a J2FlowPrinter with alternating J2TextPrinter and
J2PanelPrinter
instances to embedded Java components in a text document.
The LineSpacing ParagraphAttribute for
JTextPane doesn't work
(JDK
1.3.x and 1.4.0) -
Bug Parade 4242645
Fixed in JDK 1.4.1
The LineSpacing attribute doesn't work in JTextPane in JDK 1.3.x or
1.4. Since it doesn't work in JTextPane, there is nothing
J2TextPrinter
can do about this since J2TextPrinter can only print what JTextPane
will
draw.
Can't type characters immediately after
embedded JTable (JDK 1.3)
Fixed in JDK 1.4
This is not a printing problem, but might arise in your
working with JTextPane documents. If you use the JTextPane method
insertComponent() to embed a JTable in your JTextPane and then
place the cursor immediately after the JTable and begin typing (or
programmatically insert text), an exception
will be thrown on each keystroke due to a bug in Java (see Bug
Parade 4353673). The problem only occurs if the JTable is contained
in
a JScrollPane, but unfortunately that is the typical case since this is
how
you get JTable column headers to appear. The problem does not
occur if the JTable is inserted directly (not contained in a
JScrollPane), and
the problem does not occur for components other than JTable contained
in
a JScrollPane.
Printing is slow, especially pages with
embedded images or
components (JDK 1.2.x)
Improved in JDK 1.3, fixed in JDK 1.4
Under JDK 1.2.2, printing a full rich text page takes Java about 30
seconds, before the actual OS spooling to the printer. In
addition, due to
major performance problems in JDK 1.2.2 (see Bug
Parade 4185726), the printing of pages containing any embedded
images or components is 3-4 times slower, even if just one small image
or component is present. The J2TextPrinter background printing thread
feature is a great help in overcoming this problem for interactive
(client) applications.
Problems with JTextPane text layout (JDK
1.2.x)
Some fixed in JDK 1.3, more fixed in JDK 1.4
J2TextPrinter relies on the Java JTextPane component for its printing
functionality, including layout of text and graphics. Any
anomalies displayed using JTextPane will carry over to printing the
JTextPane component and additionally Java's JTextPane printing can
introduce anomalies of its own. The
following problems have been noted:
JTextPane tab support broken (JDK 1.2.x)
Fixed in JDK 1.3
This isn't a J2TextPrinter problem per se, but it is something people
often run into when printing. JTextPane tabs simply don't work
under JDK
1.2, even though tabs used to work in Swing. Check out the
Sun Bug Parade report 4191750 on this problem.
Here's how to set up tabs (only works in JDK 1.3 or later).
Look at the J2TextPrinterSimpleTest makeAttribute method. To set
5 tabs, 1 inch (72 "points") apart, you can add the following lines:
TabStop[] tabStopArray =
new TabStop[5];
for (int i=0; i<5;
i++) tabStopArray[i] = new TabStop((float)((i+1)*72.0));
StyleConstants.setTabSet(attribute, new TabSet(tabStopArray));
Then you simply insert "\t" (tab) characters wherever you
like in the appendStyledText method calls.
If you only need single tabs, for example to add 1" line or
paragraph indentation,
adding the following line does work under all JDK's 1.2 or later::
StyleConstants.setFirstLineIndent(attribute, (float)72.0);
Note that the size is given in printing coordinates, for which there
are 72 units per inch.
The basic rule for J2TextPrinter is that (with a very few exceptions) it will print whatever you can get JTextPane to display on the screen.
Black backgrounds when printing
transparent GIFs under Windows NT
(JDK
1.2.x)
Fixed in JDK 1.3
Under Windows NT, GIF images with transparent backgrounds print
incorrectly with black instead of transparent backgrounds due to a
known Java bug (see Bug
Parade 4175560), despite the fact that they display
correctly. Under Windows 95 and Solaris, transparent GIFs display
and print correctly. There are two workarounds for this: 1) make
your GIFs with white non-transparent backgrounds or 2) make your GIFs
with white backgrounds, specify white as your transparent color, and
change non-transparent white pixels in your
icon to near-white so they aren't transparent when displayed.
Problems printing documents containing
Chinese characters (JDK
1.2.x)
Fixed in JDK 1.3
It has come to our attention that Java will print incorrect characters
in documents containing Chinese Unicode characters under JDK
1.2.2.
The printed output will be wrong even though the J2TextPrinter print
preview is correct.
HTML printing more-or-less unusable under JDK
1.2.x
Fixed in JDK 1.3
Printing of HTML only works intermittently under JDK 1.2.2, with Java
often throwing exceptions and sometimes printing. Printing under
JDK 1.2.2 is very slow when it does work. Also, JDK 1.2.2 always
substitutes
SansSerif, even if you use the Java fonts by name. Another
problem
is that JDK 1.2.2 displays (and prints) meta tag indicators in the
document
(see Bug
Parade 4245401).