Java打印和打印预览机制实例代码
import java.awt.basicstroke;
import java.awt.borderlayout;
import java.awt.color;
import java.awt.component;
import java.awt.dimension;
import java.awt.font;
import java.awt.fontmetrics;
import java.awt.graphics;
import java.awt.graphics2d;
import java.awt.gridlayout;
import java.awt.event.actionevent;
import java.awt.event.actionlistener;
import java.awt.event.mouseadapter;
import java.awt.event.mouseevent;
import java.awt.print.pageformat;
import java.awt.print.printable;
import java.awt.print.printerexception;
import java.awt.print.printerjob;
import javax.swing.jbutton;
import javax.swing.jdialog;
import javax.swing.jframe;
import javax.swing.jpanel;
import javax.swing.jscrollpane;
import javax.swing.jtextarea;
import javax.swing.swingutilities;
import javax.swing.windowconstants;
import javax.swing.text.badlocationexception;
import javax.swing.text.document;
/**
* 使用了原始的分页方式去渲染jtextarea,提供了打印预览机制。
* <p>
* 事实上,我们还可以通过其他方式打印jtextarea:
* <ol>
* <li>{@code component.print(graphics g);} or
* {@code component.printall(graphics g);}</li>
* <li>{@code component.paint(graphics g);} or
* {@code component.paintall(graphics g);} whose rending may be slightly
* different to the previous method (for example, <code>jframe</code>)</li>
* <li>{@code jtable.print();} or {@code jtextcomponent.print();} provide
* especially powerful and convenient printing mechanism</li>
* </ol>
*
* @author gaowen
*/
public class printuicomponent extends jpanel implements actionlistener,
printable {
private static final long serialversionuid = 4797002827940419724l;
private static jframe frame;
private jtextarea textareatoprint;
private printerjob job;
private int[] pagebreaks;// array of page break line positions
private string[] textlines;
private header header;
public printuicomponent() {
super(new borderlayout());
textareatoprint = new jtextarea(50, 20);
for (int i = 1; i <= 50; i++) {
textareatoprint.append("line " + i + "\n");
}
jscrollpane scrollpane = new jscrollpane(textareatoprint);
scrollpane.setpreferredsize(new dimension(250, 200));
add(scrollpane, borderlayout.center);
jbutton printbutton = new jbutton("print this textarea");
printbutton.setname("printbutton");
printbutton.addactionlistener(this);
jbutton printpreviewbutton = new jbutton("print preview");
printpreviewbutton.setname("printpreviewbutton");
printpreviewbutton.addactionlistener(this);
jpanel buttongroup = new jpanel(new gridlayout(2, 1));
buttongroup.add(printbutton);
buttongroup.add(printpreviewbutton);
add(buttongroup, borderlayout.south);
/* initialize printerjob */
initprinterjob();
}
public static void main(string[] args) {
swingutilities.invokelater(new runnable() {
@override
public void run() {
createandshowgui();
}
});
}
private static void createandshowgui() {
frame = new jframe("print ui example");
frame.setcontentpane(new printuicomponent());
frame.pack();
frame.setlocationrelativeto(null);
frame.setdefaultcloseoperation(windowconstants.exit_on_close);
frame.setvisible(true);
}
private void inittextlines() {
document doc = textareatoprint.getdocument();
try {
string text = doc.gettext(0, doc.getlength());
textlines = text.split("\n");
} catch (badlocationexception e) {
e.printstacktrace();
}
}
private void initprinterjob() {
job = printerjob.getprinterjob();
job.setjobname("print textarea");// 出现在系统打印任务列表
job.setprintable(this);
}
@override
public int print(graphics graphics, pageformat pageformat, int pageindex)
throws printerexception {
/*
* it is safe to use a copy of this graphics as this will not involve
* changes to it.
*/
graphics2d g2 = (graphics2d) graphics.create();
/* calculate "pagebreaks" */
font font = new font("serif", font.plain, 12);
fontmetrics metrics = g2.getfontmetrics(font);
int lineheight = metrics.getheight();
if (pagebreaks == null) {
inittextlines();
int linesperpage = (int) (pageformat.getimageableheight() / lineheight);
int numbreaks = (textlines.length - 1) / linesperpage;
pagebreaks = new int[numbreaks];
for (int b = 0; b < numbreaks; b++) {
pagebreaks[b] = (b + 1) * linesperpage;
}
}
/* condition to exit printing */
if (pageindex > pagebreaks.length) {
return no_such_page;
}
/* (0,0) is outside the imageable area, translate to avoid clipping */
g2.translate(pageformat.getimageablex(), pageformat.getimageabley());
/* draw each line that is on this page */
int y = 0;
int start = (pageindex == 0) ? 0 : pagebreaks[pageindex - 1];
int end = (pageindex == pagebreaks.length) ? textlines.length
: pagebreaks[pageindex];
for (int line = start; line < end; line++) {
y += lineheight;
g2.drawstring(textlines[line], 0, y);
}
/* dispose of the graphics copy */
g2.dispose();
/* tell the caller that this page is part of the printed document */
return page_exists;
}
@override
public void actionperformed(actionevent e) {
object actioneventsource = e.getsource();
if (actioneventsource instanceof jbutton) {
jbutton button = (jbutton) actioneventsource;
if (button.getname().equals("printbutton")) {
pagebreaks = null;// reset pagination
boolean ok = job.printdialog();
if (ok) {
try {
job.print();
} catch (printerexception ex) {
/* the job did not successfully complete */
ex.printstacktrace();
}
}
} else if (button.getname().equals("printpreviewbutton")) {
pagebreaks = null;// reset pagination
createandshowpreviewdialog();
}
}
}
private void createandshowpreviewdialog() {
jdialog previewdialog = new jdialog(frame, "print preview dialog", true);
jpanel contentpane = new jpanel(new borderlayout());
previewarea previewarea = new previewarea();
previewarea.addmouselistener(new previewareamouseadapter(previewarea));
jscrollpane scrollpane = new jscrollpane(previewarea);
contentpane.add(scrollpane, borderlayout.center);
header = new header(previewarea);
contentpane.add(header, borderlayout.north);
previewdialog.setcontentpane(contentpane);
previewdialog.setsize(600, 600);
previewdialog
.setdefaultcloseoperation(windowconstants.dispose_on_close);
previewdialog.setvisible(true);
}
private class header extends component {
private static final long serialversionuid = -1741188309769027249l;
private previewarea previewarea;
private boolean paintable;
private header(previewarea previewarea) {
this.previewarea = previewarea;
}
private void setpaintable(boolean paintable) {
this.paintable = paintable;
}
@override
public void paint(graphics g) {
if (paintable) {
g.setcolor(color.gray);
g.drawstring(
string.valueof(previewarea.getpageindex() + 1)
+ "/"
+ string.valueof(pagebreaks.length + 1)
+ " pages (click left mouse button to preview next page; right to previous)",
10, 15);
}
}
@override
public dimension getpreferredsize() {
return new dimension(super.getpreferredsize().width, 20);
}
}
private class previewarea extends component {
private static final long serialversionuid = -6384174997251439843l;
private pageformat pageformat;
private int pageindex;
private int w;
private int h;
private final int marginx = 10;
private final int marginy = 20;
private previewarea() {
pageformat = job.pagedialog(job.defaultpage());
pageindex = 0;
w = (int) pageformat.getwidth();
h = (int) pageformat.getheight();
}
private int getpageindex() {
return pageindex;
}
private void setpageindex(int pageindex) {
this.pageindex = pageindex;
}
@override
public dimension getpreferredsize() {
return new dimension(w + 2 * marginx, h + 2 * marginy);
}
@override
public void paint(graphics g) {
graphics2d g2 = (graphics2d) g.create();
g2.translate(marginx, marginy);
g2.drawrect(0, 0, w, h);
int ix = (int) (pageformat.getimageablex() - 1);
int iy = (int) (pageformat.getimageabley() - 1);
int iw = (int) (pageformat.getimageablewidth() + 1);
int ih = (int) (pageformat.getimageableheight() + 1);
g2.setstroke(new basicstroke(1f, basicstroke.cap_round,
basicstroke.join_round, 10f, new float[] { 5, 5 }, 0f));
g2.drawrect(ix, iy, iw, ih);
try {
printuicomponent.this.print(g2, pageformat, pageindex);
} catch (printerexception e) {
e.printstacktrace();
}
g2.dispose();
header.setpaintable(true);
header.repaint();
}
}
private class previewareamouseadapter extends mouseadapter {
private previewarea previewarea;
private previewareamouseadapter(previewarea previewarea) {
this.previewarea = previewarea;
}
@override
public void mouseclicked(mouseevent e) {
int currentindex = previewarea.getpageindex();
if (e.getbutton() == mouseevent.button1) {
/* next page */
if (currentindex < pagebreaks.length) {
previewarea.setpageindex(currentindex + 1);
previewarea.repaint();
}
} else if (e.getbutton() == mouseevent.button3) {
/* previous page */
if (currentindex > 0) {
previewarea.setpageindex(currentindex - 1);
previewarea.repaint();
}
}
}
}
}