13

I have searched high and low for this answer and have come up blank.

I have a requirement to print the contents of a JTextPane with a footer that says "Page <n> of <m> pages". It appears to impossible to do this simple function in Java.

I can set the footer to print the page numbers when I get the Printable, e.g.


     String header = "whatever";
     String footer = " Page - {0}";
     printText(textPane.getPrintable(new MessageFormat(header), 
        new MessageFormat(footer)));

But there appears to be no way to find the total number of pages that will be printed until after the printer dialog box is dispatched. I assume that is because that dialog is used to format the pages before they are sent to the printer. The printer dialog box always says that there is only 1 (one) page.

So, I began to write a routine that will go through the JTextPane document and count the pages by getting the viewable area from the PageFormat in the print() method and then using the height of each line (fontsize) to count the lines in each page, and subsequently count the number of pages.e.g.


      int maxh = (int) pf.getImageableHeight ();
      Element section = doc.getDefaultRootElement();
      for (int i=0; i<paraCount; i++) 
      {
        Element e = section.getElement(i);
        // Get the attributeSet for this paragraph (Element)
        // The attributeSet contains the Styles, which contain
        // the fonts etc.
        AttributeSet attrs = e.getAttributes();
        int fontsize = StyleConstants.getFontSize(attrs);

        // .... add up the lines and count filled pages ...
      }

However, the PageFormat is not available until the system calls back into the print() method, and by the time it gets to the print() method, it appears to be impossible to modify the footer since the header and footer are both defined as "final" in the method call:



       public Printable getPrintable(final MessageFormat headerFormat,
                                      final MessageFormat footerFormat)

Surely somebody has found a simple way to do this basic function.

Thanks in advance for any who can help.

mKorbel
  • 108,320
  • 17
  • 126
  • 296
Banjo
  • 151
  • 4
  • MessageFormat is not final -- have you tried MessageFormat.applyPattern to alter the messages after initially specifying them but just before printing? Also, the page calculations are done in sun.swing.text.TextComponentPrintable.java. They're very complicated but maybe you could run them twice, once subclassed or redirected to bypass actual printing but get the page total and the second time to print. Just some ideas... – Boann Feb 10 '12 at 13:02
  • I have not tried any of those yet. Thank you for the tips. I am not sure how to get the header and footer for modification in the print() method. If I can somehow calculate the number of pages before I get there, it would keep the print() method simple. – Banjo Feb 10 '12 at 18:47

2 Answers2

2

I'm not sure if the links below to articles about pagination and printing of the JEditorPane/JTextPane will do the trick for you, but surely they did a lot for me:

  1. Pagination in the JEditorPane Component. Part I.
  2. Pagination in the JEditorPane Component. Part II (Printing).
  3. Pagination in the JEditorPane Component. Part III (Headers and footers).
  4. Pagination in the JEditorPane Component. Part IV (Page Breaks).
Łukasz Rżanek
  • 5,632
  • 24
  • 37
  • +1 One more article to check http://java-sl.com/JEditorPanePrinter.html It's easy to modify the paginated printer to add own footer. – StanislavL Feb 18 '12 at 16:31
1

It seems there is no "direct" way to accomplish this. The tutorial on JTextComponent says the following:

Since the total number of pages in the output is not known before printing time, there is no way to specify a numbering format like "Page 1 of 5".

jo-
  • 214
  • 1
  • 9