anner
asked on
Printing JTextArea
Hi
I have an app and have created a function that prints a JTable, but now I also need to print a JTextArea(on multiple pages). I am I newbie in the art of Java programming so I'm a bit at a loss on how this can be done. I guess I need to modify my print function so that it can print all kinds of components. Does anyone have some code that works better than mine to this purpose or a better idea on how I can solve this I would be grateful.
Thnx
I have an app and have created a function that prints a JTable, but now I also need to print a JTextArea(on multiple pages). I am I newbie in the art of Java programming so I'm a bit at a loss on how this can be done. I guess I need to modify my print function so that it can print all kinds of components. Does anyone have some code that works better than mine to this purpose or a better idea on how I can solve this I would be grateful.
Thnx
You can find some information here:
http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-Printing.html
http://www.javaworld.com/javaworld/jw-10-2000/jw-1020-print.html
http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-Printing.html
http://www.javaworld.com/javaworld/jw-10-2000/jw-1020-print.html
ASKER
Yes, I have seen these tutorials, but I find them a bit difficult to follow. It was managable while I only had to print a JTable but now that the same function has to print a JTextArea as well I'm in a little over my head
If you just want to print the contents of the text area you could just get the text of the text area and send it to the printer. If you want to print the text area itself then you could modify the exampels above. Sorry I can't offer you any exact help as I have never done any printing before.
Take a look at this URL, should be easy to use:
http://www.fawcette.com/javapro/2002_12/online/print_kgauthier_12_10_02/default_pf.asp
http://www.fawcette.com/javapro/2002_12/online/print_kgauthier_12_10_02/default_pf.asp
ASKER
Yes, I know it is the modifying bit that's the problem. Since the print function needs to print from both a table and a textarea wich are so different from eachother.
Try this method for the table:
JTable table;
.......
public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException {
int width = (int) pageFormat.getWidth();
int height = (int) pageFormat.getHeight();
g.setColor(Color.white);
g.fillRect(0, 0, width, height);
g.translate(10 * pageIndex, 10 * pageIndex);
table.print(g);
g.translate(-10 * pageIndex, -10 * pageIndex);
return 1;
}
JTable table;
.......
public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException {
int width = (int) pageFormat.getWidth();
int height = (int) pageFormat.getHeight();
g.setColor(Color.white);
g.fillRect(0, 0, width, height);
g.translate(10 * pageIndex, 10 * pageIndex);
table.print(g);
g.translate(-10 * pageIndex, -10 * pageIndex);
return 1;
}
ASKER
I call the function like this for the Table printing. The setPrintable does not seem to take a textarea as an argument. Any idea on what I'm doing wrong.
/*selectedTable=table;*/
PrinterJob pj=PrinterJob.getPrinterJo b();
pj.setPrintable(this);
pj.printDialog();
try
{
pj.print();
}
catch (Exception PrintException) {}
/*selectedTable=table;*/
PrinterJob pj=PrinterJob.getPrinterJo
pj.setPrintable(this);
pj.printDialog();
try
{
pj.print();
}
catch (Exception PrintException) {}
ASKER
I print a table fine with the first function I posted, it is printing a textarea that is causing the problem.
ASKER
>>Ovi
I looked at the URL you suggested. It seems to be a bit over my head. I was thinking more in the line of calling a different print method with a different constructor. But I'm having trouble sending the textarea to the printer. I get the priterdialog but nothing seems to be sent.
I looked at the URL you suggested. It seems to be a bit over my head. I was thinking more in the line of calling a different print method with a different constructor. But I'm having trouble sending the textarea to the printer. I get the priterdialog but nothing seems to be sent.
I believe all you have to do if you utilize the code in the previous link is:
DocumentRenderer DocumentRenderer = new DocumentRenderer();
DocumentRenderer.print(you rTextArea. getDocumen t());
DocumentRenderer DocumentRenderer = new DocumentRenderer();
DocumentRenderer.print(you
This class handle page breaks on printer. By default was designed to be used with JEditorPane objects, but (see my previous comment) it can accept in general JTextComponent instances with few modifications.
ASKER
>>DocumentRenderer DocumentRenderer = new DocumentRenderer();
>>DocumentRenderer.print(y ourTextAre a.getDocum ent());
Do you mean that this is all the modification I need to do to send the content of a JTextArea to the DocumentRenderer in the previouse link?
I tried the "easy" way and changed the JTextArea to a JEditorPane,(is there any reason way you shouldn't use a JEditorPane instead, anything a JTextArea can do that a JEditorPane can't)
>>DocumentRenderer.print(y
Do you mean that this is all the modification I need to do to send the content of a JTextArea to the DocumentRenderer in the previouse link?
I tried the "easy" way and changed the JTextArea to a JEditorPane,(is there any reason way you shouldn't use a JEditorPane instead, anything a JTextArea can do that a JEditorPane can't)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>>>"I tried the "easy" way and changed the JTextArea to a JEditorPane,(is there any reason way you shouldn't use a JEditorPane instead, anything a JTextArea can do that a JEditorPane can't)"
This is a good choice. Basically the JEditorPane does evrithing as JTextArea, but it offers to you aditional capabilities of editing and viewing html content (web pages) and RTFContent. I believe this is a huge difference. I suggest you to switch to JEditorPane.
In my previous comment I have modified (cut + modify) the oriiginal code and now you should be able to print any type of document. Please etest the program by pasting something on thet text area and then push the Print button. I have test it myself and seems to work fine, and paginates the text (paste a bigger one) very nice.
This is a good choice. Basically the JEditorPane does evrithing as JTextArea, but it offers to you aditional capabilities of editing and viewing html content (web pages) and RTFContent. I believe this is a huge difference. I suggest you to switch to JEditorPane.
In my previous comment I have modified (cut + modify) the oriiginal code and now you should be able to print any type of document. Please etest the program by pasting something on thet text area and then push the Print button. I have test it myself and seems to work fine, and paginates the text (paste a bigger one) very nice.
ASKER
Beutiful, it works, I the printer still has a problem recognizing the text format so I have to force the print but that is probably a local issue, we have just set up a printserver so problems with printing are not far between. I appreciate the code and the advice.:)
Here is an "improved" version of the class:
/* Copyright 2002
Kei G. Gauthier
Suite 301
77 Winsor Street
Ludlow, MA 01056
*/
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent ;
import java.awt.event.ActionListe ner;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterExce ption;
import java.awt.print.PrinterJob;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.Document;
import javax.swing.text.JTextComp onent;
import javax.swing.text.PlainDocu ment;
import javax.swing.text.StyledDoc ument;
import javax.swing.text.View;
import javax.swing.text.html.HTML Document;
import javax.swing.text.rtf.RTFEd itorKit;
public class DocumentRenderer implements Printable {
protected int currentPage = -1; //Used to keep track of when
//the page to print changes.
protected JTextComponent editor; //Container to hold the
//Document. This object will
//be used to lay out the
//Document for printing.
protected double pageEndY = 0; //Location of the current page
//end.
protected double pageStartY = 0; //Location of the current page
//start.
protected boolean scaleWidthToFit = true; //boolean to allow control over
//whether pages too wide to fit
//on a page will be scaled.
protected PageFormat pFormat;
protected PrinterJob pJob;
public DocumentRenderer() {
pFormat = new PageFormat();
pJob = PrinterJob.getPrinterJob() ;
}
public Document getDocument() {
if (editor != null)
return editor.getDocument();
else
return null;
}
public boolean getScaleWidthToFit() {
return scaleWidthToFit;
}
public void pageDialog() {
pFormat = pJob.pageDialog(pFormat);
}
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) {
double scale = 1.0;
Graphics2D graphics2D;
View rootView;
// I
graphics2D = (Graphics2D) graphics;
// II
editor.setSize((int) pageFormat.getImageableWid th(), Integer.MAX_VALUE);
editor.validate();
// III
rootView = editor.getUI().getRootView (editor);
// IV
if ((scaleWidthToFit) && (editor.getMinimumSize().g etWidth() > pageFormat.getImageableWid th())) {
scale = pageFormat.getImageableWid th() / editor.getMinimumSize().ge tWidth();
graphics2D.scale(scale, scale);
}
// V
graphics2D.setClip(
(int) (pageFormat.getImageableX( ) / scale),
(int) (pageFormat.getImageableY( ) / scale),
(int) (pageFormat.getImageableWi dth() / scale),
(int) (pageFormat.getImageableHe ight() / scale));
// VI
if (pageIndex > currentPage) {
currentPage = pageIndex;
pageStartY += pageEndY;
pageEndY = graphics2D.getClipBounds() .getHeight ();
}
// VII
graphics2D.translate(graph ics2D.getC lipBounds( ).getX(), graphics2D.getClipBounds() .getY());
// VIII
Rectangle allocation =
new Rectangle(0, (int) - pageStartY, (int) (editor.getMinimumSize().g etWidth()) , (int) (editor.getPreferredSize() .getHeight ()));
// X
if (printView(graphics2D, allocation, rootView)) {
return Printable.PAGE_EXISTS;
} else {
pageStartY = 0;
pageEndY = 0;
currentPage = -1;
return Printable.NO_SUCH_PAGE;
}
}
public void print(JTextComponent editor) {
this.editor = editor;
printDialog();
}
public void print(Document plainDocument) {
setDocument(plainDocument) ;
printDialog();
}
protected void printDialog() {
if (pJob.printDialog()) {
pJob.setPrintable(this, pFormat);
try {
pJob.print();
} catch (PrinterException printerException) {
pageStartY = 0;
pageEndY = 0;
currentPage = -1;
System.out.println("Error Printing Document");
}
}
}
protected boolean printView(Graphics2D graphics2D, Shape allocation, View view) {
boolean pageExists = false;
Rectangle clipRectangle = graphics2D.getClipBounds() ;
Shape childAllocation;
View childView;
if (view.getViewCount() > 0) {
for (int i = 0; i < view.getViewCount(); i++) {
childAllocation = view.getChildAllocation(i, allocation);
if (childAllocation != null) {
childView = view.getView(i);
if (printView(graphics2D, childAllocation, childView)) {
pageExists = true;
}
}
}
} else {
// I
if (allocation.getBounds().ge tMaxY() >= clipRectangle.getY()) {
pageExists = true;
// II
if ((allocation.getBounds().g etHeight() > clipRectangle.getHeight()) && (allocation.intersects(cli pRectangle ))) {
view.paint(graphics2D, allocation);
} else {
// III
if (allocation.getBounds().ge tY() >= clipRectangle.getY()) {
if (allocation.getBounds().ge tMaxY() <= clipRectangle.getMaxY()) {
view.paint(graphics2D, allocation);
} else {
// IV
if (allocation.getBounds().ge tY() < pageEndY) {
pageEndY = allocation.getBounds().get Y();
}
}
}
}
}
}
return pageExists;
}
public void setDocument(Document document) {
editor = new JEditorPane();
String contentType = "text/plain";
if (document instanceof HTMLDocument) {
contentType = "text/html";
} else if (document instanceof StyledDocument) {
contentType = "text/rtf";
}
((JEditorPane) editor).setContentType(con tentType);
editor.setDocument(documen t);
}
public void setScaleWidthToFit(boolean scaleWidth) {
scaleWidthToFit = scaleWidth;
}
public static void main(String[] args) {
JFrame f = new JFrame("JTextArea printer");
f.getContentPane().setLayo ut(new BorderLayout());
JTextComponent area = null;
try {
area = new JEditorPane("http://www.google.com");
} catch (IOException e1) {
e1.printStackTrace();
}
final Document doc = area.getDocument();
JButton print = new JButton("Print");
print.addActionListener(ne w ActionListener() {
public void actionPerformed(ActionEven t e) {
DocumentRenderer dr = new DocumentRenderer();
dr.print(doc);
}
});
JPanel p = new JPanel();
p.add(print);
f.getContentPane().add(new JScrollPane(area), BorderLayout.CENTER);
f.getContentPane().add(p, BorderLayout.SOUTH);
f.setDefaultCloseOperation (JFrame.EX IT_ON_CLOS E);
f.setSize(500, 400);
f.setLocation(200, 100);
f.setVisible(true);
}
}
/* Copyright 2002
Kei G. Gauthier
Suite 301
77 Winsor Street
Ludlow, MA 01056
*/
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent
import java.awt.event.ActionListe
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterExce
import java.awt.print.PrinterJob;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.Document;
import javax.swing.text.JTextComp
import javax.swing.text.PlainDocu
import javax.swing.text.StyledDoc
import javax.swing.text.View;
import javax.swing.text.html.HTML
import javax.swing.text.rtf.RTFEd
public class DocumentRenderer implements Printable {
protected int currentPage = -1; //Used to keep track of when
//the page to print changes.
protected JTextComponent editor; //Container to hold the
//Document. This object will
//be used to lay out the
//Document for printing.
protected double pageEndY = 0; //Location of the current page
//end.
protected double pageStartY = 0; //Location of the current page
//start.
protected boolean scaleWidthToFit = true; //boolean to allow control over
//whether pages too wide to fit
//on a page will be scaled.
protected PageFormat pFormat;
protected PrinterJob pJob;
public DocumentRenderer() {
pFormat = new PageFormat();
pJob = PrinterJob.getPrinterJob()
}
public Document getDocument() {
if (editor != null)
return editor.getDocument();
else
return null;
}
public boolean getScaleWidthToFit() {
return scaleWidthToFit;
}
public void pageDialog() {
pFormat = pJob.pageDialog(pFormat);
}
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) {
double scale = 1.0;
Graphics2D graphics2D;
View rootView;
// I
graphics2D = (Graphics2D) graphics;
// II
editor.setSize((int) pageFormat.getImageableWid
editor.validate();
// III
rootView = editor.getUI().getRootView
// IV
if ((scaleWidthToFit) && (editor.getMinimumSize().g
scale = pageFormat.getImageableWid
graphics2D.scale(scale, scale);
}
// V
graphics2D.setClip(
(int) (pageFormat.getImageableX(
(int) (pageFormat.getImageableY(
(int) (pageFormat.getImageableWi
(int) (pageFormat.getImageableHe
// VI
if (pageIndex > currentPage) {
currentPage = pageIndex;
pageStartY += pageEndY;
pageEndY = graphics2D.getClipBounds()
}
// VII
graphics2D.translate(graph
// VIII
Rectangle allocation =
new Rectangle(0, (int) - pageStartY, (int) (editor.getMinimumSize().g
// X
if (printView(graphics2D, allocation, rootView)) {
return Printable.PAGE_EXISTS;
} else {
pageStartY = 0;
pageEndY = 0;
currentPage = -1;
return Printable.NO_SUCH_PAGE;
}
}
public void print(JTextComponent editor) {
this.editor = editor;
printDialog();
}
public void print(Document plainDocument) {
setDocument(plainDocument)
printDialog();
}
protected void printDialog() {
if (pJob.printDialog()) {
pJob.setPrintable(this, pFormat);
try {
pJob.print();
} catch (PrinterException printerException) {
pageStartY = 0;
pageEndY = 0;
currentPage = -1;
System.out.println("Error Printing Document");
}
}
}
protected boolean printView(Graphics2D graphics2D, Shape allocation, View view) {
boolean pageExists = false;
Rectangle clipRectangle = graphics2D.getClipBounds()
Shape childAllocation;
View childView;
if (view.getViewCount() > 0) {
for (int i = 0; i < view.getViewCount(); i++) {
childAllocation = view.getChildAllocation(i,
if (childAllocation != null) {
childView = view.getView(i);
if (printView(graphics2D, childAllocation, childView)) {
pageExists = true;
}
}
}
} else {
// I
if (allocation.getBounds().ge
pageExists = true;
// II
if ((allocation.getBounds().g
view.paint(graphics2D, allocation);
} else {
// III
if (allocation.getBounds().ge
if (allocation.getBounds().ge
view.paint(graphics2D, allocation);
} else {
// IV
if (allocation.getBounds().ge
pageEndY = allocation.getBounds().get
}
}
}
}
}
}
return pageExists;
}
public void setDocument(Document document) {
editor = new JEditorPane();
String contentType = "text/plain";
if (document instanceof HTMLDocument) {
contentType = "text/html";
} else if (document instanceof StyledDocument) {
contentType = "text/rtf";
}
((JEditorPane) editor).setContentType(con
editor.setDocument(documen
}
public void setScaleWidthToFit(boolean
scaleWidthToFit = scaleWidth;
}
public static void main(String[] args) {
JFrame f = new JFrame("JTextArea printer");
f.getContentPane().setLayo
JTextComponent area = null;
try {
area = new JEditorPane("http://www.google.com");
} catch (IOException e1) {
e1.printStackTrace();
}
final Document doc = area.getDocument();
JButton print = new JButton("Print");
print.addActionListener(ne
public void actionPerformed(ActionEven
DocumentRenderer dr = new DocumentRenderer();
dr.print(doc);
}
});
JPanel p = new JPanel();
p.add(print);
f.getContentPane().add(new
f.getContentPane().add(p, BorderLayout.SOUTH);
f.setDefaultCloseOperation
f.setSize(500, 400);
f.setLocation(200, 100);
f.setVisible(true);
}
}
Thanks.
ASKER
public int print(Graphics g, PageFormat pageFormat,int pageIndex) throws PrinterException
{
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.black);
int fontHeight=g2.getFontMetri
int fontDesent=g2.getFontMetri
//leave room for page number
double pageHeight = pageFormat.getImageableHei
double pageWidth = pageFormat.getImageableWid
double tableWidth =(double) selectedTable.getColumnMod
double scale = 1;
if (tableWidth >= pageWidth)
{
scale = pageWidth / tableWidth;
}
double headerHeightOnPage = selectedTable.getTableHead
double tableWidthOnPage=tableWidt
double oneRowHeight=(selectedTabl
int numRowsOnAPage = (int)((pageHeight-headerHe
double pageHeightForTable=oneRowH
int totalNumPages= (int)Math.ceil(((double)se
if(pageIndex>=totalNumPage
{
System.out.println("Ingen utskrift");
return NO_SUCH_PAGE;
}
g2.translate(pageFormat.ge
g2.drawString("Page: "+(pageIndex+1),(int)pageW
g2.translate(0f,headerHeig
g2.translate(0f,-pageIndex
//TODO this next line treats the last page as a full page
g2.setClip(0, (int)(pageHeightForTable*p
g2.scale(scale,scale);
selectedTable.paint(g2);
g2.scale(1/scale,1/scale);
g2.translate(0f,pageIndex*
g2.translate(0f, -headerHeightOnPage);
g2.setClip(0, 0,(int) Math.ceil(tableWidthOnPage
g2.scale(scale,scale);
selectedTable.getTableHead
return Printable.PAGE_EXISTS;
}