import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import .Graphics2D;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
/**
* Use the original pagination method to render JTextArea, providing a print preview mechanism.
* <p>
* In fact, we can print JTextArea in other ways:
* <ol>
* <li>{@code (Graphics g);} or
* {@code (Graphics g);}</li>
* <li>{@code (Graphics g);} or
* {@code (Graphics g);} whose rending may be slightly
* different to the previous method (for example, <code>JFrame</code>)</li>
* <li>{@code ();} or {@code ();} 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++) {
("Line " + i + "\n");
}
JScrollPane scrollPane = new JScrollPane(textAreaToPrint);
(new Dimension(250, 200));
add(scrollPane, );
JButton printButton = new JButton("Print This TextArea");
("printButton");
(this);
JButton printPreviewButton = new JButton("Print Preview");
("printPreviewButton");
(this);
JPanel buttonGroup = new JPanel(new GridLayout(2, 1));
(printButton);
(printPreviewButton);
add(buttonGroup, );
/* Initialize PrinterJob */
initPrinterJob();
}
public static void main(String[] args) {
(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
frame = new JFrame("Print UI Example");
(new PrintUIComponent());
();
(null);
(WindowConstants.EXIT_ON_CLOSE);
(true);
}
private void initTextLines() {
Document doc = ();
try {
String text = (0, ());
textLines = ("\n");
} catch (BadLocationException e) {
();
}
}
private void initPrinterJob() {
job = ();
("Print TextArea");// Appears in the system printing task list
(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) ();
/* Calculate "pageBreaks" */
Font font = new Font("Serif", , 12);
FontMetrics metrics = (font);
int lineHeight = ();
if (pageBreaks == null) {
initTextLines();
int linesPerPage = (int) (() / lineHeight);
int numBreaks = ( - 1) / linesPerPage;
pageBreaks = new int[numBreaks];
for (int b = 0; b < numBreaks; b++) {
pageBreaks[b] = (b + 1) * linesPerPage;
}
}
/* Condition to exit printing */
if (pageIndex > ) {
return NO_SUCH_PAGE;
}
/* (0,0) is outside the imageable area, translate to avoid clipping */
((), ());
/* Draw each line that is on this page */
int y = 0;
int start = (pageIndex == 0) ? 0 : pageBreaks[pageIndex - 1];
int end = (pageIndex == ) ?
: pageBreaks[pageIndex];
for (int line = start; line < end; line++) {
y += lineHeight;
(textLines[line], 0, y);
}
/* dispose of the graphics copy */
();
/* Tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
}
@Override
public void actionPerformed(ActionEvent e) {
Object actionEventSource = ();
if (actionEventSource instanceof JButton) {
JButton button = (JButton) actionEventSource;
if (().equals("printButton")) {
pageBreaks = null;// reset pagination
boolean ok = ();
if (ok) {
try {
();
} catch (PrinterException ex) {
/* The job did not successfully complete */
();
}
}
} else if (().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();
(new PreviewAreaMouseAdapter(previewArea));
JScrollPane scrollPane = new JScrollPane(previewArea);
(scrollPane, );
header = new Header(previewArea);
(header, );
(contentPane);
(600, 600);
previewDialog
.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
(true);
}
private class Header extends Component {
private static final long serialVersionUID = -1741188309769027249L;
private PreviewArea previewArea;
private boolean paintable;
private Header(PreviewArea previewArea) {
= previewArea;
}
private void setPaintable(boolean paintable) {
= paintable;
}
@Override
public void paint(Graphics g) {
if (paintable) {
();
(
(() + 1)
+ "/"
+ ( + 1)
+ " pages (Click left mouse button to preview next page; right to previous)",
10, 15);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(().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 = (());
pageIndex = 0;
w = (int) ();
h = (int) ();
}
private int getPageIndex() {
return pageIndex;
}
private void setPageIndex(int pageIndex) {
= pageIndex;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(w + 2 * marginX, h + 2 * marginY);
}
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) ();
(marginX, marginY);
(0, 0, w, h);
int ix = (int) (() - 1);
int iy = (int) (() - 1);
int iw = (int) (() + 1);
int ih = (int) (() + 1);
(new BasicStroke(1f, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND, 10f, new float[] { 5, 5 }, 0f));
(ix, iy, iw, ih);
try {
(g2, pageFormat, pageIndex);
} catch (PrinterException e) {
();
}
();
(true);
();
}
}
private class PreviewAreaMouseAdapter extends MouseAdapter {
private PreviewArea previewArea;
private PreviewAreaMouseAdapter(PreviewArea previewArea) {
= previewArea;
}
@Override
public void mouseClicked(MouseEvent e) {
int currentIndex = ();
if (() == MouseEvent.BUTTON1) {
/* next page */
if (currentIndex < ) {
(currentIndex + 1);
();
}
} else if (() == MouseEvent.BUTTON3) {
/* previous page */
if (currentIndex > 0) {
(currentIndex - 1);
();
}
}
}
}
}