I'm getting really lost trying to work out how to print charts to a printer with jfreechart. After browsing this forum I found that it can be done from a right click menu on the chart, via a method in the chartpanel class.
I have a problem though that I have a really long chart that I want to print all of, split across several pages. I don't know how to properly send this to the printer. In addition I'm having problems with the printer seeing some annotations and displaying only a few dates on the x-axis.
Any help for a relatve newbie would be much appreciated.
Print chart on many pages?(Still Stuck :( Please help asap!)
Print chart on many pages?(Still Stuck :( Please help asap!)
Last edited by ormstont on Tue Aug 15, 2006 12:58 pm, edited 2 times in total.
Ok, thanks for the advice but still running into problems.
I've written code that successfully steps the chart along its length by resetting the ranges each time. If I place a printjob in every range update then each section prints properly.
However..I want to print all the sections as one print job. I've tried adding them to a book but it only prints out the last range update I've done, doesn't seem to store the previous ones. My code is as follows:
The top section is the end of the iteration loop, where it appends the chart panel to the Book using the default settings. Please any help given would be great, am really getting tight on time now and no nearing to solving it!!
I've written code that successfully steps the chart along its length by resetting the ranges each time. If I place a printjob in every range update then each section prints properly.
However..I want to print all the sections as one print job. I've tried adding them to a book but it only prints out the last range update I've done, doesn't seem to store the previous ones. My code is as follows:
Code: Select all
mtpBook.append(this.panel, pf);
}
//PrinterJob printJob = PrinterJob.getPrinterJob();
PrinterJob printJob = PrinterJob.getPrinterJob();
//Do the print
printJob.setPageable(mtpBook);
if (printJob.printDialog())
{
try
{
printJob.print();
}
catch (Exception PrintException)
{
PrintException.printStackTrace();
}
}
Have you looked at the java printing tutorial at Sun's site?
Here is some old documentation that may help:
Printing with Pageables and Books
Pageable jobs are suited for applications that build an explicit
representation of a document, page by page. The Book class is a
convenient way to use Pageables, but you can also build your own
Pageable structures if Book does not suit your needs. This section
focusses on Book, because it is easy to use.
Although slightly more involved, Pageable jobs are preferred over
Printable jobs because the printing system has more flexibility. A
major advantage of Pageables is that the number of pages in the
document is usually known, and can be displayed to the user in the
print dialog box. This helps the user to confirm that the job is
specified correctly or to select a range of pages for printing.
A Book represents a collection of pages. The pages in a book do not
have to share the same size, orientation, or page painter. For example,
a Book might contain two letter size pages in portrait orientation,
followed by a letter size page in landscape orientation.
When a Book is first constructed, it is empty. To add pages to a
Book, you use the append method. This method takes a PageFormat
object that defines the page's size, printable area, and orientation
and a page painter that implements the Printable interface.
Multiple pages in a Book can share the same page format and painter.
The append method is overloaded to enable you to add a series of
pages that have the same attributes by specifying a third parameter,
the number of pages.
If you don't know the total number of pages in a Book, you can
specify UNKNOWN_NUMBER_OF_PAGES in a call to append. In this case,
the printing system will call you page painters in order of increasing
page index until a page painter returns the value NO_SUCH_PAGE. [xxx
This is not clear in the JavaDoc. Can I do something like:
bk.append(title-painter, title-format, 1); bk.append(body-painter,
body-format, UNKNOWN_NUMBER_OF_PAGES); ]
The setPage method can be used to change a page's page format or
painter. The page to be changed is identified by a page index that
indicates the page's location in the book.
To print a book, it is offered to a PrinterJob using the
setPageable method. The setPageable and setPrintable methods are
mutually exclusive; that is, you should call one or the other but not
both when preparing a PrinterJob.
The first example of the use of Book recasts the first Printable
job example (PrintSimple) to use the Book abstraction. This case
is so simple that the virtues of using a Book are not readily
apparent.
import java.awt.*;
import java.awt.print.*;
public class SimplePrintBook implements Printable {
private static Font fnt = new Font("Helvetica", Font.PLAIN, 24);
public static void main(String[] args) {
// Obtain a PrinterJob
PrinterJob job = PrinterJob.getPrinterJob();
// Set up a book
Book bk = new Book();
bk.append(new SimplePrintBook(), job.defaultPage(), 5);
// Pass the book to the PrinterJob
job.setPageable(bk);
// Put up the dialog box
if (job.printDialog()) {
// Print the job if the user didn't cancel printing
try { job.print(); }
catch (Exception e) { /* should handle */ }
}
System.exit(0);
}
public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
g.setFont(fnt);
g.setColor(Color.green);
g.drawString("Page " + (pageIndex+1), 100, 100);
return Printable.PAGE_EXISTS;
}
}
The following example shows a more complex using two page painters, one
for a cover page and one for content pages. The cover page is printed
in landscape mode. Two pages of contents are printed in portrait
mode.
import java.awt.*;
import java.awt.print.*;
public class PrintBook {
public static void main(String[] args) {
// Obtain a PrinterJob
PrinterJob job = PrinterJob.getPrinterJob();
// Create a landscape page format
PageFormat pfl = job.defaultPage();
pfl.setOrientation(PageFormat.LANDSCAPE);
// Set up a book
Book bk = new Book();
bk.append(new PaintCover(), pfl);
bk.append(new PaintContent(), job.defaultPage(), 2);
// Pass the book to the PrinterJob
job.setPageable(bk);
// Put up the dialog box
if (job.printDialog()) {
// Print the job if the user didn't cancel printing
try { job.print(); }
catch (Exception e) { /* should handle */ }
}
System.exit(0);
}
}
class PaintCover implements Printable {
Font fnt = new Font("Helvetica-Bold", Font.PLAIN, 72);
public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
g.setFont(fnt);
g.setColor(Color.black);
g.drawString("Widgets, Inc.", 36, 210);
return Printable.PAGE_EXISTS;
}
}
class PaintContent implements Printable {
public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
Graphics2D g2 = (Graphics2D) g;
int useRed = 0;
// Fill page with circles or squares, alternating red & green
for (int x = 0; x < pf.getImageableWidth(); x += 36)
for (int y = 0; y < pf.getImageableHeight(); y += 36) {
if (useRed == 0) g.setColor(Color.red);
else g.setColor(Color.green);
useRed = 1 - useRed;
if (pageIndex % 2 == 0) g.drawRect(x+4, y+4, 28, 28);
else g.drawOval(x+4, y+4, 28, 28);
}
return Printable.PAGE_EXISTS;
}
}
Here is some old documentation that may help:
Printing with Pageables and Books
Pageable jobs are suited for applications that build an explicit
representation of a document, page by page. The Book class is a
convenient way to use Pageables, but you can also build your own
Pageable structures if Book does not suit your needs. This section
focusses on Book, because it is easy to use.
Although slightly more involved, Pageable jobs are preferred over
Printable jobs because the printing system has more flexibility. A
major advantage of Pageables is that the number of pages in the
document is usually known, and can be displayed to the user in the
print dialog box. This helps the user to confirm that the job is
specified correctly or to select a range of pages for printing.
A Book represents a collection of pages. The pages in a book do not
have to share the same size, orientation, or page painter. For example,
a Book might contain two letter size pages in portrait orientation,
followed by a letter size page in landscape orientation.
When a Book is first constructed, it is empty. To add pages to a
Book, you use the append method. This method takes a PageFormat
object that defines the page's size, printable area, and orientation
and a page painter that implements the Printable interface.
Multiple pages in a Book can share the same page format and painter.
The append method is overloaded to enable you to add a series of
pages that have the same attributes by specifying a third parameter,
the number of pages.
If you don't know the total number of pages in a Book, you can
specify UNKNOWN_NUMBER_OF_PAGES in a call to append. In this case,
the printing system will call you page painters in order of increasing
page index until a page painter returns the value NO_SUCH_PAGE. [xxx
This is not clear in the JavaDoc. Can I do something like:
bk.append(title-painter, title-format, 1); bk.append(body-painter,
body-format, UNKNOWN_NUMBER_OF_PAGES); ]
The setPage method can be used to change a page's page format or
painter. The page to be changed is identified by a page index that
indicates the page's location in the book.
To print a book, it is offered to a PrinterJob using the
setPageable method. The setPageable and setPrintable methods are
mutually exclusive; that is, you should call one or the other but not
both when preparing a PrinterJob.
The first example of the use of Book recasts the first Printable
job example (PrintSimple) to use the Book abstraction. This case
is so simple that the virtues of using a Book are not readily
apparent.
import java.awt.*;
import java.awt.print.*;
public class SimplePrintBook implements Printable {
private static Font fnt = new Font("Helvetica", Font.PLAIN, 24);
public static void main(String[] args) {
// Obtain a PrinterJob
PrinterJob job = PrinterJob.getPrinterJob();
// Set up a book
Book bk = new Book();
bk.append(new SimplePrintBook(), job.defaultPage(), 5);
// Pass the book to the PrinterJob
job.setPageable(bk);
// Put up the dialog box
if (job.printDialog()) {
// Print the job if the user didn't cancel printing
try { job.print(); }
catch (Exception e) { /* should handle */ }
}
System.exit(0);
}
public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
g.setFont(fnt);
g.setColor(Color.green);
g.drawString("Page " + (pageIndex+1), 100, 100);
return Printable.PAGE_EXISTS;
}
}
The following example shows a more complex using two page painters, one
for a cover page and one for content pages. The cover page is printed
in landscape mode. Two pages of contents are printed in portrait
mode.
import java.awt.*;
import java.awt.print.*;
public class PrintBook {
public static void main(String[] args) {
// Obtain a PrinterJob
PrinterJob job = PrinterJob.getPrinterJob();
// Create a landscape page format
PageFormat pfl = job.defaultPage();
pfl.setOrientation(PageFormat.LANDSCAPE);
// Set up a book
Book bk = new Book();
bk.append(new PaintCover(), pfl);
bk.append(new PaintContent(), job.defaultPage(), 2);
// Pass the book to the PrinterJob
job.setPageable(bk);
// Put up the dialog box
if (job.printDialog()) {
// Print the job if the user didn't cancel printing
try { job.print(); }
catch (Exception e) { /* should handle */ }
}
System.exit(0);
}
}
class PaintCover implements Printable {
Font fnt = new Font("Helvetica-Bold", Font.PLAIN, 72);
public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
g.setFont(fnt);
g.setColor(Color.black);
g.drawString("Widgets, Inc.", 36, 210);
return Printable.PAGE_EXISTS;
}
}
class PaintContent implements Printable {
public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
Graphics2D g2 = (Graphics2D) g;
int useRed = 0;
// Fill page with circles or squares, alternating red & green
for (int x = 0; x < pf.getImageableWidth(); x += 36)
for (int y = 0; y < pf.getImageableHeight(); y += 36) {
if (useRed == 0) g.setColor(Color.red);
else g.setColor(Color.green);
useRed = 1 - useRed;
if (pageIndex % 2 == 0) g.drawRect(x+4, y+4, 28, 28);
else g.drawOval(x+4, y+4, 28, 28);
}
return Printable.PAGE_EXISTS;
}
}
That's a great tutorial, and thanks very much - my trawls of google hadn't picked that one up (searching for a class called 'Book' is a bit tricky!).
Unfortunately I've looked over it and the only difference in the implementation compared to my code is that they add the page number on the end of the 'append' call. I've tried doing that but still doesn't change anything.
I think it may be something to do with the chart panel not being added to the book in the first place. Does it need to be repainted in the book? or redrawn? Getting this from the fact that if you create a print job for each 'new page' it does print correctly, just in a stack of jobs. Any help would be very gratefully recieved!
Unfortunately I've looked over it and the only difference in the implementation compared to my code is that they add the page number on the end of the 'append' call. I've tried doing that but still doesn't change anything.
I think it may be something to do with the chart panel not being added to the book in the first place. Does it need to be repainted in the book? or redrawn? Getting this from the fact that if you create a print job for each 'new page' it does print correctly, just in a stack of jobs. Any help would be very gratefully recieved!