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();
}
&nbs